Правило хорошего тона Delphi (Memory leaks)

Ни кто ни где особо не рассказывает об этом новичкам, но я расскажу. В Delphi важно очищать за собой инициализированные тобой объекты. Чтобы не засорять выделенную программе память. Это делает метод “Free”. Он есть в каждом классе.

var
  Icon: TIcon;
begin
  Icon := TIcon.Create; //Создаем иконку
  try
    GetIconFromFile(FullName, Icon, SHIL_EXTRALARGE);
    ImageIcon.Picture.Assign(Icon); //Используем
  finally
    Icon.Free; //Освобождаем
  end;
end;

Это важно, потому что даже локально (объявленный в текущем методе) созданный объект останется в рабочем состоянии после выхода из процедуры. И его желательно уничтожить перед выходом из процедуры.
В противном случае, объект остается в памяти и занимает собой выделенную ему память. Это называют утечкой (leak).
Для того, чтоб узнать, есть ли в программе утечки памяти нужно где-нибудь в начале программы вставить строчку:

ReportMemoryLeaksOnShutdown := True;

Обычно это делается в основном файле программы dpr.
Эта штука выведет сообщение об ошибке после завершения программы, если в программе есть утечки. А также, покажет подробности.

 Вот например, я создал панель и забил на неё:

procedure TFormMain.FormCreate(Sender: TObject);
begin
  TPanel.Create(nil);
end;

Да, панель даже не будет показана на форме, также, я не указал владельца, и кстати, именно по этому она не уничтожится вместе с формой.

Объекты, которые были созданы для панели и сама панель, которую мы не освободили

Что произойдёт после завершения программы? – Форма уничтожится как обычно, а вот созданная нами панель будет в памяти и подчищать за нами будет уже операционная система.
На самом деле этот случай не так страшен, ведь мы создали лишь одну панель при создании формы и ОС уже привыкла чистить за программами.

Но проблема будет крайне велика, когда мы будем создавать объекты в цикле или по событию и не следить за ними, пусть даже они нам больше не нужны. Занимаемая программой оперативная память будет расти и расти, пока программа не крашнется из-за того, что мы использовали всю данную нам ОЗУ (до 3 гб для 32-битных программ и пока не кончится вся ОЗУ для 64-битных программ). Это важно для программ, которые работают 24/7, ведь рано или поздно они начнут тормозить всю систему и в конечном итоге упадут сами или перестанут нормально функционировать.

Избежать подобного поможет слежение за объектами. Т.е. вы всегда должны знать, когда объект создается и когда он будет уничтожен.
Уникальные классы создаваемые в FormCreate уничтожать в FormDestroy и т.д.
И не забывайте использовать ReportMemoryLeaksOnShutdown := True; для проверки.
Рекомендую обернуть этот флаг, чтобы подобное отображалось только в отладочной версии программы:

{$IFDEF DEBUG}
  ReportMemoryLeaksOnShutdown := True;
{$ENDIF}

Всем стабильных программ!

You may also like...

1 Response

  1. 30.01.2020

    […] Постоянных и основных всего два метода: GetInstance и DestroyInstance. Первый метод предоставляет доступ к методам класса, а второй позволяет безопасно уничтожить синглтон. Теоретически, последний метод не обязателен, т.к. объект класса всегда будет один и утечек памяти на стадии работы программы быть не может. Утечка произойдёт только после закрытия программы, когда самой программе это уже не важно. Но не забываем про правила хорошего тона. […]

Добавить комментарий

Войти с помощью: