Подтвердить что ты не робот

Delphi. Повторное компиляция приложения с 10.2.1 вызывает утечку памяти?

Я только что установил Delphi 10.2 Release 1. Когда я перекомпилировал свои приложения и запускал их, у меня много утечек памяти. У меня не было утечек памяти с 10.2 (без обновления). Я также не внес изменений в код.

Чтобы проверить, я создал простое пустое приложение и поместил несколько компонентов в форму. Нет кода. Отказались от приложения и получили утечки памяти. Утечки памяти из примера приложения

Я хотел выделить это (если только предупреждение перед обновлением).

Мои вопросы:

  • Кто-нибудь еще видел эту проблему?
  • Есть ли что-то, что мне нужно или может сделать, чтобы избавиться от этой проблемы?

Примечание.. Я зарегистрировал проблему на портале качества, на всякий случай, это настоящая проблема: https://quality.embarcadero.com/browse/RSP-18774. В этом билете я также приложил пример приложения.

4b9b3361

Ответ 1

После некоторого расследования я обнаружил, что обратные вызовы, передаваемые TThread.CurrentThread.ForceQueue в TStyledControl.KillResourceLink, никогда не выполняются, потому что прежде чем какой-либо поток сможет обрабатывать их, приложение заканчивается, а деструктор класса TThread уничтожает список, который все еще имеет необработанные обратные вызовы.

Я решил это, добавив вызов CheckSynchronize в конце FMX.Forms.DoneApplication, который заставляет выполнять обратные вызовы, которые устраняли огромную утечку памяти.

Я не знаю, правильно ли это исправление, но оно решило сообщить о утечке памяти.

Ответ 2

У меня такая же проблема с использованием С++ Builder 10.2.1 в FMX и в приложениях VCL.

Если я включу CodeGuard, я получаю утечки памяти при выходе приложения.

У меня есть TThread с обработчиком OnTerminate: если я поставлю точку останова в этом обработчике, когда я закрываю программу, она никогда не вызывается.

Если я помещаю CheckSynchronize() в деструктор моей основной формы приложения, проблема остается.

Мое решение было "ужасным" циклом, подобным этому в деструкторе основной формы:

__fastcall TForm3::~TForm3(void) {
    for(int i = 0; i < 10; i++) {
        Sleep(1);
        CheckSynchronize();
    }
}

Это решение не является детерминированным, но может использоваться в вашем приложении в режиме отладки, чтобы избежать сообщений об ошибках CodeGuard.

Другое решение использует функцию WaitFor(), если MyThread является объектом TThread:

MyThread = new MyThreadClass();

и DeleteThisTh() - это метод этого класса, мы можем дождаться завершенного потока внутри DeleteThisTh():

void MyThreadClass::DeleteThisTh(void) {
    Terminate();
    WaitFor();
    delete this;
}

В событии OnTerminate я могу очистить свои объекты. Обратите внимание:

  • delete this вызывается после OnTerminate;
  • DeleteThisTh() живет в основном потоке;