内存泄漏检测和周期

时间:2018-05-25 19:22:45

标签: android delphi memory-leaks delphi-10.1-berlin

我尝试使用来自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不同,我认为没有办法联系作者。否则我会先问他们。

1 个答案:

答案 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示例。