delphi – TTaskBar内存泄漏

前端之家收集整理的这篇文章主要介绍了delphi – TTaskBar内存泄漏前端之家小编觉得挺不错的,现在分享给大家,也给大家做个参考。
Embarcadero的TTaskbar有内存泄漏.由于我在表单上删除了此控件,因此每次关闭应用程序时,FastMM都会报告泄漏.

我尝试使用以下代码将FastMM静音:

  1. procedure TMainForm.FormCreate(Sender: TObject);
  2. begin
  3. fastmm4.RegisterExpectedMemoryLeak(Taskbar);
  4. end;

但它不会起作用.如何注册此泄漏?

A memory block has been leaked. The size is: 100

This block was allocated by thread 0xC64,and the stack trace (return
addresses) at the time was: 406A52 409A7B 409CAC 4283A0

[System.SysUtils][System][System.SysUtils.FmtStr] 409CC6 40D775
7628A65F
[Unknown function at StretchDIBits] 7731594E
[Unknown function at RtlpNtMakeTemporaryKey] 7731594E
[Unknown function at RtlpNtMakeTemporaryKey] 773168F8
[Unknown function at RtlpNtMakeTemporaryKey] 773168DC
[Unknown function at RtlpNtMakeTemporaryKey]

The block is currently used for an object of class: UnicodeString
The allocation number is: 2209

A memory block has been leaked. The size is: 36

This block was allocated by thread 0xC64,and the stack trace (return
addresses) at the time was: 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]

The block is currently used for an object of class: ETaskbarException
The allocation number is: 2207

This application has leaked memory. The small block leaks are (excluding expected leaks registered by pointer):

21 – 36 bytes: ETaskbarException x 1
85 – 100 bytes: UnicodeString x 1
[Vcl.Forms][Vcl][Vcl.Forms.TCustomForm.SetVisible] 5F5010

解决方法

内存从System.Win.TaskbarCore泄漏到此代码中:
  1. procedure TTaskbarBase.UpdateTab;
  2. var
  3. LpfIsiconic: LONGBOOL;
  4. LHandle: HWND;
  5. LFlags: Integer;
  6. begin
  7. if FTaskbarIsAvailable then
  8. begin
  9. LHandle := GetFormHandle;
  10. if not FRegistered and TaskBar.RegisterTab(LHandle) then
  11. begin
  12. TaskBar.SetTabOrder(LHandle);
  13. TaskBar.SetTabActive(LHandle);
  14. FRegistered := True;
  15. end
  16. else
  17. ETaskbarException.CreateFmt(SCouldNotRegisterTabException,[TaskBar.LastError]);
  18. ....

最后一行创建一个异常,然后对它不执行任何操作.它拥有的异常和字符串被泄露.据FastMM报道.

如果您可以获取其地址,则可以将这些对象注册为泄露.但是,你不能这样做.无法引用此异常对象.

如果您只是必须避免这种错误报告的泄漏,并且您有意义,那么您需要在项目中包含固定版本的System.Win.TaskbarCore.制作该文件的副本,并将其添加到您的项目中.然后修改代码以修复故障.我的猜测是它会像这样:

  1. if not FRegistered then
  2. begin
  3. if TaskBar.RegisterTab(LHandle) then
  4. begin
  5. TaskBar.SetTabOrder(LHandle);
  6. TaskBar.SetTabActive(LHandle);
  7. FRegistered := True;
  8. end
  9. else
  10. raise ETaskbarException.CreateFmt(SCouldNotRegisterTabException,[TaskBar.LastError]);
  11. end;

显然,这需要向Embarcadero报告.我建议您提交错误报告.

另一种方法是尽量避免伪造线执行.我相信如果你从.dfm文件删除这一行,你应该避免虚假行,因此避免泄漏:

  1. Visible = True

只需删除该行,它似乎是触发器.

请注意,我通过将项目切割成裸露的骨头来解决这个问题.为了重现这个问题,这是所需的最小dfm文件

  1. object Form1: TMainForm
  2. Visible = True
  3. object Taskbar1: TTaskbar
  4. end
  5. end

并使用此dfm文件没有泄漏:

  1. object Form1: TMainForm
  2. object Taskbar1: TTaskbar
  3. end
  4. end

通过将项目减少到最低限度,我能够找到触发器.我不能强调这种最小化再现技术的价值.

感谢Remy为此故障找到质量控制报告:QC#128865

猜你在找的Delphi相关文章