at general, if any "memory leaks" occurrs then "it should be guilt of developer" not necessary from language! of course, if any bug on language it's not guilt from developer!
basic rules:
0) put this command your .DPR file - try catch the "memory leaks" in Delphi - native!!!
ReportMemoryLeaksOnShutdown := true;
1) if you "create" any instance of object, YOU SHOULD RELEASE/FREE!
2) if you use "interfaces", normally, the "garbase collector - GC / ARC technic should take care about it" ... but each case is a new case!!! need study about!
3) always that necessary, use "TRY... FINALLY ... END;". if necessary use "TRY... EXCEPT...END;" nested.
-- NOTE: DONT ABUSE OF THIS USAGE AT ALL PLACES IN YOUR CODE! BE CLEAN! BE PROFESSIONAL!
4) if you dont have certain about if needs "free" or "not free" you instance object.... DO TESTS... with Free or without Free!
if you needs test your code in Posix platfoms, like ANDROID, try this tool:
LeakCheck (Free) +/- 2 MBytes sources
Delphi LeakCheck is another great option for detecting memory leaks. It’s also free, open source, and has some advantages over FastMM: it’s cross-platform, meaning you can check leaks directly in mobile and Linux applications; and it integrates very well with unit test frameworks (namely DUnit and DUnitX).
The way to get started with it is similar to FastMM: add LeakCheck unit as the first used unit in your dpr uses clause, and it will plugin and be ready to use. Setting up for unit testing is a little more complicated though, but that’s part of the game.
One small disadvantage is that to use it you are almost on your own: the project hasn’t received updates for a while (which isn’t necessarily bad since it’s working).
But that means probably you won’t get much help directly from the author (I never tried, to be fair).
There is also not much information about it in the web, I just found one single article that explains how to use it besides the detailed description in the official Bitbucket repository itself.
Pros - Free; - Full source code; - Cross-plataform; - Integrates well with unit testing (DUnit and DUnitX).
Cons - Not much information around about how to use it; - No recent updates, no official support;
https://bitbucket.org/shadow_cs/delphi-leakcheck
NOTE: dont use it in your commercial software!!! why? because it's not have support!
before all try this:
code: myInstanceObj : TMyObjectClass;
procedure XXXXX; var myInstanceObj : TMyObjectClass; begin // I create, I kill. myInstanceObj := TMyObjectClass.Create; try try ... more code except // // you can verify the "exception category" if necessary // On E:EDivideByZero do // exception when any number divided by zero = 4/0=??? begin
end; On E:Exception do // generic exceptions begin // what to do with this error? end; // // etc... end; finally // usage default: myInstanceObj.Free; MyInstanceObj := nil; // to avoid access it again in another place... because Delphi dont release the pointer-address by default! // // in Posix, use: // myInstanceObj.DisposeOf; // myInstanceObj := nil; // // using FreeAndNil(...) do the same above in just 1 line // FreeAndNil( myInstanceOjb ); end;
----------------------------------------------
The higher the degree, the greater the respect given to the humblest!RAD 11.3
.... {$IF Defined(MACOS) OR Defined(IOS) OR Defined(LEAK_REPORT_DOCUMENTS)} BasePath := TPath.GetDocumentsPath; BaseName := ExtractFileName(ParamStr(0)); {$ELSEIF Defined(MSWINDOWS)} BasePath := ExtractFilePath(ParamStr(0)); BaseName := ExtractFileName(ParamStr(0)); {$ELSEIF Defined(ANDROID)} // Note that this requires Read/Write External Storage permissions // Write permissions option is enough, reading will be available as well BasePath := '/storage/emulated/0/'; BaseName := 'LeakCheck_Log'; {$IFEND} BasePath := TPath.Combine(BasePath, ChangeFileExt(BaseName, ''));
FLogFileName := BasePath + '.log'; FGraphFileName := BasePath + '.dot'; end;
----------------------------------------------
The higher the degree, the greater the respect given to the humblest!RAD 11.3
{$IFDEF ANDROID} PermissionsService.RequestPermissions(MyArrayPermissions, MyRequestPermissionsResult); // if PermissionsService.IsEveryPermissionGranted(MyArrayPermissions) then begin GetMyDirectories; end else TDialogService.ShowMessage('This permissions ("ReadStorage" and "WriteStorage") is necessary for this task!'); {$ELSE} GetMyDirectories; {$ENDIF}