6
votes

For a web framework I tried anonymous methods for the first time and ran into a problem with the memory management.

How can this memory leak (Delphi 2009) get fixed?

The leak message is:

13 - 20 bytes: Project27$ActRec x 1

program Project27;

type
  TTestProc = reference to procedure;

  procedure CallMe(Proc: TTestProc);
  begin
  end;

begin
  CallMe(procedure begin end);

  ReportMemoryLeaksOnShutdown := True;
end.

The same leak message "Project27$ActRec x 1" appears no matter how many anonymous methods are between begin and end, I guess that the leak is for the TTestProc type, not the individual anonymous procedures

program Project27;

type
  TTestProc = reference to procedure;

  procedure CallMe(Proc: TTestProc);
  begin
  end;

begin

  ReportMemoryLeaksOnShutdown := True;

  CallMe(procedure begin end);

  CallMe(procedure var A: Integer; begin A := 42 ; end);

end. 
2

2 Answers

16
votes

When you declare an anonymous method inside a procedure or function, it gets cleaned up when that routine goes out of scope. (This is an oversimplification, but it's good enough for the current discussion.) The problem is that the DPR's main routine does not "go out of scope." Instead, the Delphi compiler inserts a hidden call to System.Halt at the end of it, which never returns.

So if you write it this way, you're going to get the memory leak notification. You can fix it by putting the anonymous method creation inside a routine that exits normally, like so:

program Project27;

type
  TTestProc = reference to procedure;

  procedure CallMe(Proc: TTestProc);
  begin
  end;

  procedure Test;
  begin
    CallMe(procedure begin end);
  end;

begin
  Test;
  ReportMemoryLeaksOnShutdown := True;
end.
10
votes

I guess this is because your are using the main begin..end. block inside the .dpr file. The hidden memory structures created within the begin..end. scope is not released when FastMM4 inspects the memory, because it is not yet out of scope.

There is no memory leak if you put your anonymous method outside this main begin..end. block.

My advice is to avoid putting some code inside the .dpr file - it is most of the time buggy. And the IDE does not like that. Use a separated unit for your own code, and leave the .dpr content alone. :)