我们在Delphi中处理第三方组件线程代码的方式上一直存在问题。我说第三方是因为我们的核心应用程序没有单独实现任何多线程代码。我所确定的是,如果我使用SimpleShareMem (我们有几个dll与主应用程序共享字符串数据),就会发生奇怪的内存损坏,但是如果安装FastMM4单元,这些错误就会消失。奇怪的是,我的意思是,这些错误很少是连续两次相同的,尽管它们在相同的范围内。我最初安装FastMM4是为了尝试确定错误的原因,但实际上它们在安装时根本不会发生。我已经在我的选项集中设置了条件,允许我在SimpleShareMem和FastMM之间来回翻转项目组中的所有模块,并且可以很容易地演示我的结论。
我的直接例子是TRichView。我已经了解到,当我使用Hun拼写拼写检查器时,我可以在PaintBuffered/PaintTo过程中或附近产生一个错误,方法是同时粘贴和单击-向上滚动相当多次(不同的是,我需要这样做多少次才能产生错误)。有时是外部异常解决了表面异常,另一些时候我在异常处理代码中达到堆栈溢出。
我遇到的另一个例子是AnyDAC (DA-软)远程/文件监控系统,它也运行在一个独立的线程中,它不能与SimpleShareMem一起工作,但是可以与FastMM4一起工作。
基于这些经验,我不得不使用FastMM4单元进行生产构建,尽管这在我看来可能很奇怪。当然,我总是首先怀疑我自己的代码,所以我想知道我是否可以做些什么来加剧这个问题,尽管FastMM4没有显示主应用程序有任何堆栈损坏等等。
所以,我的问题是,有谁能想到为什么FastMM4比Delphi使用的任何版本的FastMM更适合多线程操作呢?
更新:我想补充的是,我现在已经使用了旧的Sharemem/borIndmm.dll概念进行了一些测试,这也很好。
更新2:谢谢您的建议。我一直在努力寻找导致我的问题的黑头虫,但没有取得什么成功。我还有一个额外的观察。
如果我修改主应用程序,使其不加载需要ShareMem的DLL,那么无论使用哪个内存管理器,无论是AnyDAC日志记录还是TRichView,我都没有问题。加载dll的行为本身(它启动FastMM的初始实例并与主应用程序共享)将导致问题,即使我没有调用该DLL。接下来我要做的是修改主应用程序以启用dll的动态加载(从而强制内存管理器安装到主应用程序中),看看这是否会产生影响。
更新3:动态加载与不加载it...everything工作具有相同的效果。
发布于 2011-11-04 17:54:32
Delphi中嵌入的内存管理器是FastMM4的一个精简版本。
内存块分配器本身是相同的,但共享机制并不相同。
默认情况下,在FastMM4Options.inc中设置下列条件
{Define this to enable backward compatibility for the memory manager sharing
mechanism used by Delphi 2006 and 2007, as well as older FastMM versions.}
{$define EnableBackwardCompatibleMMSharing}它将为库创建一个隐藏的窗口句柄,以检索共享内存管理器实例--这是它如何使用Delphi 2006和2007的。
这种共享在自Delphi2009以来在FastMM4中实现的GetMem.inc的缩减版本中不再存在,后者只实现共享内存管理器文件映射(这是一种新方法)。其中一个库可能需要旧版本的内存管理器共享,无法找到共享内存管理器实例,因此使用它自己的内存分配器-并且在处理共享内存(如string实例)时失败。
这是我在这两个版本中发现的唯一不同之处,这也可能是共享在您的程序中不能正常工作的原因。您可能有一些使用Delphi 2006或2007编译的库,Embarcadero不推荐使用共享方法(以保存一些字节的代码?)。
https://stackoverflow.com/questions/8013278
复制相似问题