在Delphi XE中,我总是使用ReportMemoryLeaksOnShutDown
来检测退出我的应用程序时的任何泄漏,大多数我的项目都很小,并且发现泄漏通常并不太困难。
在Lazarus中没有这样的选择,但我刚刚找到了一个名为Heaptrcon的选项,有关此页面的更多信息:http://wiki.lazarus.freepascal.org/Profiling
在项目选项>链接我设置了(-gh)标志,现在我对任何泄漏的恐惧已成为现实。我会发布代码,但因为有很多不同的类和单元我不知道从哪里开始修复这些泄漏,这是一个比我工作过的任何其他项目都要大的项目。
这是一些漏洞的截图:
我的调试技巧几乎为零,到目前为止,我已经查看了我创建的每个对象或类,然后检查它是否已被释放。因为我正在使用很多TLists和Pointers / Objects等,所以我猜想泄漏可能来自任何地方。
是否有任何线索或提示甚至可以从哪里开始寻找?我正在查看大小为16的每个块的调用堆栈,其中有6个,这是否意味着有6个对象未被正确销毁?
我不知所措,从哪里开始?
提前致谢。
答案 0 :(得分:3)
您真正需要的信息是与每个泄漏对象关联的分配的堆栈跟踪。它们出现在屏幕截图中,但显示为地址而不是函数名称。启用调试信息,名称将显示给您。然后,您可以像在Delphi中使用FastMM一样跟踪问题。
答案 1 :(得分:2)
正如David Heffernan先前在其中一篇评论中提到的,应该有办法将这些地址转换为函数名称。
第一步是确保我已启用Generate debugging info for GDB
由于某种原因未启用,然后我获得了这些函数名称。
在追踪地址后,他们将我带到了我的TList对象。现在我正在研究的这个项目实际上是在Delphi XE中启动的,但是我移植到了Lazarus,并且在XE中没有选择这些错误,但在释放我的TList Objects时我做到了这一点:
var
P: Pointer;
begin
for P in MyList do TMyListItem(P).Free;
end;
我没有安装XE进行测试,但我记得上面没有错误。
我还在Treeview中添加了对象(那些对象是MyList
的指针),我没有释放它们。但即使这样做,我的泄漏仍然存在。
经过几个小时尝试不同的事情并接近放弃,我意识到我错过了一些简单的事情:
var
P: Pointer;
begin
for P in MyList do TMyListItem(P).Free;
MyList.Free;
end;
我在Delphi中错过了那部分而且我很肯定它并没有抱怨任何泄漏,但在Lazarus / FPC我得到了大量的新泄漏。到目前为止,我所有的泄漏都已经消失了(希望如此),并且不会再回来了。
现在我收到这份泄漏报告,因为它报告了zero
泄漏,因此看起来不那么可怕了: