我尝试使用来自https://bitbucket.org/shadow_cs/的跨平台内存泄漏检测代码。
我写了一个包含循环的小型Android演示应用程序:
type
TMyClassA = class(TObject)
public
Other : TMyClassA;
end;
procedure TForm1.Button1Click(Sender: TObject);
var
a, b: TMyClassA;
begin
a := TMyClassA.Create;
b := TMyClassA.Create;
a.Other := b;
b.Other := a;
end;
然后我在Android上运行它(将所需的单元添加到项目,库路径等)。
当我按下按钮并退出应用程序时,我可以看到大量关于logcat泄漏的消息,但它似乎永远不会结束。
这是由于我的周期吗?
如果是,我需要做什么,为什么不显示泄露的对象的名称,只显示他们的地址?
摘自logcat:
05-25 21:00:14.257: W/leak(8382): Leak detected CC4BC740 size 48 B 05-25 21:00:14.266: W/leak(8382): 01 00 00 00 0A 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ???????????????????????????????? 05-25 21:00:14.302: W/leak(8382): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ???????????????? 05-25 21:00:14.334: W/leak(8382): Leak detected CC4BCEC0 size 48 B 05-25 21:00:14.366: W/leak(8382): 01 00 00 00 0A 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ???????????????????????????????? 05-25 21:00:14.400: W/leak(8382): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ???????????????? 05-25 21:00:14.425: W/leak(8382): Leak detected CC4B1E40 size 256 B 05-25 21:00:14.467: W/leak(8382): 40 AD 6B CA C0 0F 4C CC 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | @?k???L????????????????????????? 05-25 21:00:14.503: W/leak(8382): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 48 12 4C CC 00 00 00 00 | ????????????????????????H?L????? 05-25 21:00:14.543: W/leak(8382): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 48 1C 4C CC C8 14 4C CC 00 00 00 00 00 00 00 00 | ????????????????H?L???L????????? 05-25 21:00:14.573: W/leak(8382): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ???????????????????????????????? 05-25 21:00:14.605: W/leak(8382): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ???????????????????????????????? 05-25 21:00:14.639: W/leak(8382): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ???????????????????????????????? 05-25 21:00:14.674: W/leak(8382): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ???????????????????????????????? 05-25 21:00:14.708: W/leak(8382): 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 | ????????????????????????????????
泄漏检测项目托管在Bitbucket上。我是那个新手,但与GitHub不同,我认为没有办法联系作者。否则我会先问他们。
答案 0 :(得分:1)
是的,这是由于周期。为了防止这些泄漏,您必须手动取消分配它们或使用[Weak]
属性,以便编译器/ RTL知道可能的循环,并且在分配给弱字段时引用计数不会增加,而是“记住”分配并且在释放对象时取消分配字段(因此您不会访问已释放的实例,但在进入该场景时仍然会获得nil-pointer AV)。另一个选项是使用[Unsafe]
(或指定/取消分配您的实例为Pointer(fField) := instance
),这样可以完全禁止ARC和弱引用。
LeakCheck报告所有内存泄漏,但只有一些类型包含其他信息,因此类型可以被iknferred(LeakCheck支持字符串/对象),所以你忽略那些未知数是正确的。
LeakCheck确实实现了循环检测,并以Graphviz DOT格式输出,以便可视化。我建议使用文件记录(在LeakCheck.Report.FileLog
之后将LeakCheck
添加到项目中)它会将泄漏和图形输出到单独的文件中(请记住,目标文件夹/storage/emulated/0/
需要可访问通过应用程序)所以它比logcat输出更容易传输处理。有关详细信息,请参阅CustomLeakReportFMX
示例。