Delphi - 使用 10.2.1 重新编译应用程序会导致内存泄漏?

Delphi - Recompiling application with 10.2.1 causes memory leaks?

我刚刚安装了 Delphi 10.2 第 1 版。当我重新编译我的应用程序和 运行 它们时,我遇到了很多内存泄漏。我在 10.2(没有更新)时没有内存泄漏。我也没有更改代码。

为了验证,我创建了一个简单的空白应用程序并在表单上放置了一些组件。没有代码。 运行 应用程序并报告了内存泄漏。

我想强调这一点(如果只是作为升级前的警告)。

我的问题:

  1. 还有其他人看到过这个问题吗?
  2. 我需要或可以做些什么来解决这个问题吗?

注意: 我已经在质量门户上记录了一个问题,以防这是一个真正的问题:https://quality.embarcadero.com/browse/RSP-18774。在这张票中,我还附上了示例应用程序。

经过一些调查,我发现在 TStyledControl.KillResourceLink 中传递给 TThread.CurrentThread.ForceQueue 的回调从未执行过,因为在任何线程可以处理它们之前,应用程序正在结束并且 TThread class 析构函数正在销毁仍有未处理回调的列表。

我通过在 FMX.Forms.DoneApplication 末尾添加对 CheckSynchronize 的调用来解决这个问题,这会强制执行回调,从而解决了巨大的内存泄漏问题。

我不知道这是否是解决问题的正确方法,但它解决了所报告的内存泄漏问题。

我在 FMX 和 VCL 应用程序中使用 C++Builder 10.2.1 时遇到同样的问题。

如果启用 CodeGuard,我会在应用程序退出时发生内存泄漏。

我有一个 TThreadOnTerminate 处理程序:如果我在这个处理程序中放置一个断点,当我关闭程序时它永远不会被调用。

如果我将 CheckSynchronize() 放入主应用程序的析构函数中,问题仍然存在。

我的解决方案是在主窗体的析构函数中使用这样的 "horrible" 循环:

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

此解决方案不是确定性的,但可以在您的应用程序中以调试模式使用以避免出现 CodeGuard 错误消息。

如果 MyThread 是一个 TThread 对象,另一个解决方案是使用 WaitFor() 函数:

MyThread = new MyThreadClass();

DeleteThisTh()是这个class的一个方法,我们可以在DeleteThisTh():

里面等待终止线程
void MyThreadClass::DeleteThisTh(void) {
    Terminate();
    WaitFor();
    delete this;
}

OnTerminate事件中,我可以清理我的物品。注意:

  1. delete thisOnTerminate 之后调用;
  2. DeleteThisTh()住在主线程;