13

我刚刚安装了 Delphi 10.2 Release 1。当我重新编译我的应用程序并运行它们时,我得到了很多内存泄漏。10.2(没有更新)我没有内存泄漏。我也没有对代码进行任何更改。

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

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

我的问题:

  1. 有没有其他人看到这个问题?
  2. 我需要或可以做些什么来摆脱这个问题?

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

4

2 回答 2

18

经过一番调查,我发现传递给TThread.CurrentThread.ForceQueuein的回调TStyledControl.KillResourceLink永远不会执行,因为在任何线程可以处理它们之前,应用程序已经结束,并且TThread类析构函数正在破坏仍然具有未处理回调的列表。

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

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

于 2017-08-09T14:33:25.823 回答
0

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

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

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

如果我放入CheckSynchronize()主申请表的析构函数,问题仍然存在。

我的解决方案是在主窗体的析构函数中出现这样的“可怕”循环:

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

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

另一种解决方案是使用WaitFor()函数 ifMyThread是一个TThread对象:

MyThread = new MyThreadClass();

并且DeleteThisTh()是这个类的一个方法,我们可以在里面等待终止的线程DeleteThisTh()

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

在这种情况OnTerminate下,我可以清理我的物品。记笔记:

  1. delete this在之后调用OnTerminate
  2. DeleteThisTh()住在主线程中;
于 2017-10-24T14:42:30.647 回答