Анонимный метод в проекте утечки памяти - PullRequest
6 голосов
/ 14 февраля 2012

Для веб-фреймворка я впервые попробовал анонимные методы и столкнулся с проблемой управления памятью.

Как исправить эту утечку памяти (Delphi 2009)?

Сообщение об утечке:

13 - 20 байтов: 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.

Одно и то же сообщение об утечке «Project27 $ ActRec x 1» появляется независимо от того, сколько анонимных методов находится между началом и концом, я думаю, что утечка относится к типу TTestProc, а не к отдельным анонимным процедурам

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 ]

16 голосов
/ 14 февраля 2012

Когда вы объявляете анонимный метод внутри процедуры или функции, он очищается, когда эта подпрограмма выходит из области видимости. (Это упрощение, но оно достаточно для текущего обсуждения.) Проблема в том, что основная программа ДНР не «выходит за рамки». Вместо этого компилятор Delphi вставляет скрытый вызов System.Halt в конце, который никогда не возвращается.

Так что, если вы напишите это так, вы получите уведомление об утечке памяти. Вы можете исправить это, поместив создание анонимного метода в обычную процедуру, например, так:

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 голосов
/ 14 февраля 2012

Полагаю, это потому, что вы используете основной блок begin..end. внутри файла .dpr.Скрытые структуры памяти, созданные в области действия begin..end., не освобождаются, когда FastMM4 проверяет память, поскольку она еще не находится вне области действия.

При установкеанонимный метод за пределами этого основного begin..end. блока.

Мой совет: не помещайте некоторый код в файл .dpr - в большинстве случаев он глючит.И IDE не нравится это.Используйте отдельный блок для своего собственного кода и оставьте содержимое .dpr в покое. :)

...