WeG*_*ars 7 delphi fastmm leakcheck
Embarcadero的TTaskbar有内存泄漏.由于我在表单上删除了此控件,因此每次关闭应用程序时,FastMM都会报告泄漏.
我尝试使用以下代码将FastMM静音:
procedure TMainForm.FormCreate(Sender: TObject);
begin
fastmm4.RegisterExpectedMemoryLeak(Taskbar);
end;
Run Code Online (Sandbox Code Playgroud)
但它不会起作用.如何注册此泄漏?
内存块已泄露.大小是:100
该块由线程0xC64分配,当时的堆栈跟踪(返回地址)为:406A52 409A7B 409CAC 4283A0
[System.SysUtils] [System] [System.SysUtils.FmtStr] 409CC6 40D775 7628A65F
[StretchDIBits的未知功能] 7731594E
[RtlpNtMakeTemporaryKey上的
未知函数] 7731594E
[ RtlpNtMakeTemporaryKey上的未知函数] 773168F8
[ RtlpNtMakeTemporaryKey上的未知函数] 773168DC [ RtlpNtMakeTemporaryKey上的未知函数]该块当前用于类的对象:UnicodeString
分配编号为:2209内存块已泄露.大小是:36
该块由线程0xC64分配,当时的堆栈跟踪(返回地址)为:406A52 407D43 40846A 42CD40
[System.SysUtils] [System] [System.SysUtils.Exception.CreateFmt] 5DEDD7
[System.Win.TaskbarCore] [System.Win] [System.Win.TaskbarCore.TTaskbarBase.UpdateTab] 610F00
[Vcl.Taskbar] [Vcl] [Vcl.Taskbar.CheckMDI] 5DF39F
[System.Win.TaskbarCore] [System.Win] [System.Win. TaskbarCore.TTaskbarBase.ApplyTabsChanges] 610DB8
[Vcl.Taskbar] [Vcl] [Vcl.Taskbar.TCustomTaskbar.Initialize] 5EB044
[Vcl.Forms] [Vcl] [Vcl.Forms.TApplication.Run] 62573A
[MinimalTemplate.dpr] [MinimalTemplate ] [MinimalTemplate.MinimalTemplate] [26]该块当前用于类的对象:ETaskbarException
分配编号为:2207此应用程序已泄露内存.小块泄漏(不包括指针注册的预期泄漏):
21 - 36字节:ETaskbarException x 1
85 - 100字节:UnicodeString x 1
[Vcl.Forms] [Vcl] [Vcl.Forms.TCustomForm.SetVisible] 5F5010
Dav*_*nan 10
内存泄漏在此代码中System.Win.TaskbarCore:
procedure TTaskbarBase.UpdateTab;
var
LpfIsiconic: LONGBOOL;
LHandle: HWND;
LFlags: Integer;
begin
if FTaskbarIsAvailable then
begin
LHandle := GetFormHandle;
if not FRegistered and TaskBar.RegisterTab(LHandle) then
begin
TaskBar.SetTabOrder(LHandle);
TaskBar.SetTabActive(LHandle);
FRegistered := True;
end
else
ETaskbarException.CreateFmt(SCouldNotRegisterTabException, [TaskBar.LastError]);
....
Run Code Online (Sandbox Code Playgroud)
最后一行创建一个异常,然后对它不执行任何操作.它拥有的异常和字符串被泄露.据FastMM报道.
如果您可以获取其地址,则可以将这些对象注册为泄露.但是,你不能这样做.无法引用此异常对象.
如果您只是必须避免这种错误报告的泄漏,并且您有意义,那么您需要System.Win.TaskbarCore在项目中包含固定版本.制作该文件的副本,并将其添加到您的项目中.然后修改代码以修复故障.我的猜测是它会像这样:
if not FRegistered then
begin
if TaskBar.RegisterTab(LHandle) then
begin
TaskBar.SetTabOrder(LHandle);
TaskBar.SetTabActive(LHandle);
FRegistered := True;
end
else
raise ETaskbarException.CreateFmt(SCouldNotRegisterTabException, [TaskBar.LastError]);
end;
Run Code Online (Sandbox Code Playgroud)
显然,这需要向Embarcadero报告.我建议您提交错误报告.
另一种方法是尽量避免伪造线执行.我相信如果你从.dfm文件中删除这一行,你应该避免虚假行,因此避免泄漏:
Visible = True
Run Code Online (Sandbox Code Playgroud)
只需删除该行,它似乎是触发器.
请注意,我通过将项目切割成裸露的骨头来解决这个问题.为了重现这个问题,这是所需的最小dfm文件:
object Form1: TMainForm
Visible = True
object Taskbar1: TTaskbar
end
end
Run Code Online (Sandbox Code Playgroud)
并使用此dfm文件没有泄漏:
object Form1: TMainForm
object Taskbar1: TTaskbar
end
end
Run Code Online (Sandbox Code Playgroud)
通过将项目减少到最低限度,我能够找到触发器.我不能强调这种最小化再现技术的价值.
感谢Remy为此故障找到QC报告:QC#128865
| 归档时间: |
|
| 查看次数: |
476 次 |
| 最近记录: |