Понимать и предотвращать утечки памяти в Delphi

DelphiПоддержка объектно-ориентированного программирования богата и мощна. Классы и объекты позволяют программировать модульный код. Наряду с более модульными и более сложными компонентами появляются более сложные и более сложные ошибки.

При разработке приложения в Delphi Это (почти) всегда весело, бывают ситуации, когда вы чувствуете, что весь мир против вас.

Всякий раз, когда вам нужно использовать (создавать) объект в Delphi, вам необходимо освободить память, которую он потреблял (когда-то больше не нужно). Конечно, блоки try / finally, защищающие память, могут помочь вам предотвратить утечки памяти; это все еще зависит от вас, чтобы защитить ваш код.

Утечка памяти (или ресурса) происходит, когда программа теряет способность освобождать память, которую она использует. Повторные утечки памяти приводят к тому, что использование памяти процессом растет без ограничений. Утечки памяти являются серьезной проблемой - если у вас есть код, вызывающий утечку памяти, в приложении, работающем Круглосуточно приложение израсходует всю доступную память и, наконец, перестанет отвечать на запросы машины.

instagram viewer

Утечки памяти в Delphi

Первый шаг к предотвращению утечек памяти - понять, как они происходят. Далее следует обсуждение некоторых распространенных ошибок и передовых методов написания непротекающего кода Delphi.

В большинстве (простых) приложений Delphi, где вы используете компоненты (кнопки, заметки, изменения и т. Д.), Которые вы помещаете в форму (во время разработки), вам не нужно слишком заботиться об управлении памятью. Как только компонент помещен в форму, форма становится его владелец и освободит память, занятую компонентом, как только форма будет закрыта (уничтожена). Форма, как владелец, отвечает за освобождение памяти компонентов, которые она размещает. Короче говоря: компоненты на форме создаются и уничтожаются автоматически

Примеры утечек памяти

В любом нетривиальном приложении Delphi вы захотите создание компонентов Delphi во время выполнения. Также у вас будут свои собственные классы. Допустим, у вас есть класс TDeveloper, у которого есть метод DoProgram. Теперь, когда вам нужно использовать класс TDeveloper, вы создаете экземпляр класса, вызывая Создайте метод (конструктор). Метод Create выделяет память для нового объекта и возвращает ссылку на объект.

вар
zarko: TDeveloper
начать
zarko: = TMyObject. Создайте;
Жарко. DoProgram;
конец;

А вот и простая утечка памяти!

Всякий раз, когда вы создаете объект, вы должны распоряжаться памятью, которую он занимал. Чтобы освободить память выделенного объекта, вы должны вызвать Свободно метод. Чтобы быть абсолютно уверенным, вы также должны использовать блок try / finally:

вар
zarko: TDeveloper
начать
zarko: = TMyObject. Создайте;
пытаться
Жарко. DoProgram;
наконец
Жарко. Свободно;
конец;
конец;

Это пример безопасного выделения памяти и освобождения кода.

Несколько слов предостережения: Если вы хотите динамически создать экземпляр компонента Delphi и явно освободить его через некоторое время, всегда передавайте nil в качестве владельца. Невыполнение этого требования может привести к ненужному риску, а также к проблемам с производительностью и обслуживанием кода.

Помимо создания и уничтожения объектов с использованием методов Create и Free, вы также должны быть очень осторожны при использовании «внешних» (файлы, базы данных и т. Д.) Ресурсов.
Допустим, вам нужно работать с некоторым текстовым файлом. В очень простом сценарии, где метод AssignFile используется для связи файла на диске с файлом переменная, когда вы закончите с файлом, вы должны вызвать CloseFile, чтобы освободить дескриптор файла, чтобы начать используемый. Это где у вас нет явного вызова «бесплатно».

вар
F: TextFile;
S: строка;
начать
AssignFile (F, 'c: \ somefile.txt');
пытаться
Readln (F, S);
наконец
Закрыть файл (F);
конец;
конец;

Другой пример включает загрузку внешних DLL из вашего кода. Всякий раз, когда вы используете LoadLibrary, вы должны вызывать FreeLibrary:

вар
dllHandle: THandle;
начать
dllHandle: = Loadlibrary ('MyLibrary. DLL ');
// сделать что-нибудь с этой DLL
если dllHandle <> 0, то FreeLibrary (dllHandle);
конец;

Утечки памяти в .NET?

Хотя в Delphi для .NET сборщик мусора (GC) управляет большинством задач с памятью, в приложениях .NET возможны утечки памяти. Вот обсуждение статьи GC в Delphi для .NET.

Как бороться с утечками памяти

Помимо написания модульного безопасного кода памяти, предотвращение утечек памяти может быть сделано с помощью некоторых доступных сторонних инструментов. Delphi Инструменты для устранения утечек памяти поможет вам поймать приложение Delphi ошибки такие как повреждение памяти, утечки памяти, ошибки выделения памяти, ошибки инициализации переменной, конфликты определения переменной, ошибки указателя и многое другое.

instagram story viewer