I'm working with Delphi XE, and writing an application that is using RemObjects SDK to communicate (in case that may be relevant). I have FastMM debug on, and sometimes (not always) when I close it gives a warning about a single "Unexpected Memory Leak". "An unexpected memory leak has occurred. The unexpected small block leaks are: 117-124 bytes: UnicodeString x 1". Very occasionally, I get x2 reported.
Now, my understanding is that Strings are reference counted, and since there is no other object involved to cause the leak, what might be the situation that could cause this to happen? In this StackOverflow question people cannot find a way to make a leak.
If there is no obvious way, then I will download the latest FastMM source (it appears not to be included with the XE source).
[Edit once resolved] The solution to finding this was to install FastMM source, and enable the FullDebugMode to get the stack trace.
When using typed constants and depending on finalization order, it used to be possible for FastMM to report a leak when there really isn't.
FastMM: Leaked memory reported where I believe it shouldn't.
In short, when the FinalizedFirst unit get's finalized, the SString constant get's freed. After finalization of the unit is done, the finalization of FinalizedLast get's called. In it is finalization, it call's the method LeakMemory of the FinalizedFirst method. The SString variable gets initialized again and doesn't get freed as the finalization of FinalizedFirst has already run.
FinalizedLast Unit
unit FinalizedLast;
interface
uses FinalizedFirst;
implementation
initialization LeakMemory;
finalization LeakMemory;
end.
FinalizedFirst Unit
unit FinalizedFirst;
interface
procedure LeakMemory;
implementation
uses FinalizedLast;
procedure LeakMemory;
const
SString: string = '';
begin
//***** SString will get initialized once or twice depending on the
// finalization order of units. If it get's initialized twice,
// a memory leak is reported.
if SString = '' then
SString := 'FooBar';
end;
end.
Project LeakMemory
program LeakMemory;
uses
FastMM4 in 'FastMM4.pas',
Forms,
FinalizedFirst in 'FinalizedFirst.pas',
FinalizedLast in 'FinalizedLast.pas';
{$R *.RES}
begin
Application.Initialize;
Application.Run;
end.
You can leak strings by freeing records on the heap using FreeMem instead of Dispose or if you overwrite a record using System.Move or FillChar. In the first case the finalization code isn't run and in the second if the string field was filled with a nil it will think it's already cleared it.
If you want to find the location for the leak download FastMM and turn on FullDebugMode. It will include a stack trace of where the leak occurred.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With