Delphi - 使用 10.2.1 重新编译应用程序会导致内存泄漏?
Delphi - Recompiling application with 10.2.1 causes memory leaks?
我刚刚安装了 Delphi 10.2 第 1 版。当我重新编译我的应用程序和 运行 它们时,我遇到了很多内存泄漏。我在 10.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,我会在应用程序退出时发生内存泄漏。
我有一个 TThread
和 OnTerminate
处理程序:如果我在这个处理程序中放置一个断点,当我关闭程序时它永远不会被调用。
如果我将 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
事件中,我可以清理我的物品。注意:
delete this
在 OnTerminate
之后调用;
DeleteThisTh()
住在主线程;
我刚刚安装了 Delphi 10.2 第 1 版。当我重新编译我的应用程序和 运行 它们时,我遇到了很多内存泄漏。我在 10.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,我会在应用程序退出时发生内存泄漏。
我有一个 TThread
和 OnTerminate
处理程序:如果我在这个处理程序中放置一个断点,当我关闭程序时它永远不会被调用。
如果我将 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
事件中,我可以清理我的物品。注意:
delete this
在OnTerminate
之后调用;DeleteThisTh()
住在主线程;