Reputation: 170
I tried to use a cross platform memory leak detection code from https://bitbucket.org/shadow_cs/.
I wrote a small Android demo app containing a cycle:
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;
And then I run it on Android (added the needed units to the project, library paths, etc).
When I press the button and quit the application, I can see tons of messages about something leaking in logcat, but it seems to never end.
Is this due to my cycle?
If yes, what do I need to do, and why doesn't it show the name of the objects leaked but only their addresses?
Excerpt from 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 | ????????????????????????????????
The project of the leak detection is hosted on Bitbucket. I'm new to that one, but unlike GitHub I don't see any way to contact the authors. Otherwise I'd have asked them first.
Upvotes: 1
Views: 274
Reputation: 711
Yes it is due to the cycles. In order to prevent those leaks you have to either manually unassign them or use [Weak]
attribute so the compiler/RTL knows about possible cycles and the reference count is not incremented when assigning to weak fields, instead it "remembers" the assignment and unassigns the field when the objects is freed (so you won't access freed instance but still get an nil-pointer AV when you get in that scenario). Another option is to use [Unsafe]
(or assign/unassign your instance as Pointer(fField) := instance
) which inhibits ARC and Weak references altogether.
LeakCheck reports all memory leaks but only some types contain additional information so type can be iknferred (LeakCheck supports strings/objects), so you were right to ignore those unknowns.
LeakCheck does implement cycle detection and outputs it in Graphviz DOT format so it can be visualized. I'd recommend using file logging (add LeakCheck.Report.FileLog
to your project AFTER LeakCheck
) it will output the leaks and graph to separate files (keep in mind the destination folder /storage/emulated/0/
needs to be accessible by the app) so it is easier to transfer for processing than logcat output. Refer to CustomLeakReportFMX
sample for more details.
Upvotes: 1