Delphi 10.2使用FastMM4时DLL与主程序交互出现内存泄漏
FastMM4检测到UnicodeString内存泄漏的原因及解决办法
核心原因是UnicodeString的内存分配器上下文不匹配,主程序和DLL默认各自使用独立的内存分配实例,跨模块传递字符串后会导致释放逻辑失效:
- 主程序传递的
UnicodeString内存由主程序的FastMM4分配,DLL将其赋值给全局变量ownData后,该字符串的引用计数操作在DLL的上下文执行,但内存归属仍属于主程序的分配器。 - 程序关闭时,若DLL先被卸载,其FastMM4会尝试释放全局变量中的字符串,但这块内存并非由它分配,释放操作失败,FastMM4判定为内存泄漏;若主程序先退出,其分配器已销毁,DLL后续无法正确释放持有的字符串引用,同样会触发泄漏告警。
- 当你在DLL中把
ownData.test改为固定值时,新字符串的内存由DLL自身的FastMM4分配,卸载时分配器能正常释放,因此不会报告泄漏。
解决办法
- 共享FastMM4分配器:在主程序和DLL的项目中都添加
ShareMM编译指令,确保两者使用同一个内存分配实例,这样跨模块的字符串分配、释放和引用计数操作能正常协同。 - 显式拷贝字符串到DLL内存空间:在DLL的
Testcall函数中接收字符串时,主动创建DLL上下文的副本,比如:
这样字符串内存由DLL的分配器管理,卸载时可正常释放。ownData.test := String(Copy(TransferData.test)); - 主动清理全局变量:在DLL的
DllMain函数的DLL_PROCESS_DETACH阶段,将ownData.test置为空字符串,触发引用计数归零,让主程序的分配器能正确回收内存:case fdwReason of DLL_PROCESS_DETACH: ownData.test := ''; end;
内容的提问来源于stack exchange,提问作者White
相关产品推荐
相关产品推荐

