【问题标题】:Ran AQTime on my application and maybe found Memory Leak在我的应用程序上运行 AQTime,可能发现内存泄漏
【发布时间】:2011-03-12 03:41:59
【问题描述】:

我正在运行一个在 Windows 7 下使用 RAD Studio XE 或 Delphi XE 开发的应用程序。从以前的项目文件重建我的应用程序后,我一直在测试它的功能,但该应用程序只能运行大约一个月左右并启动慢慢地失败。除非 Windows 操作系统出现故障,否则此应用程序应该一直 24/7 运行。因此,我在应用程序上运行了几个小时的 AQTime,并在程序运行时密切关注结果。我注意到的是这个。在其他一切都保持不变且数量仍然存在的情况下,在资源配置下,画笔、手柄、笔和另一支笔的数量正在缓慢增加,尤其是第二支笔和画笔资源。钢笔的数量似乎每秒增加约 522 支。此外,句柄的数量正在增加,但非常缓慢 - 可能每 15 分钟一次。附带说明:我们的一些用户总共有 灾难性故障,Windows 操作系统将完全死机,以至于您必须重新安装 Windows 以及其他所有内容。

AQTime result:
Class_Name     Object_Name
Brush          Brush:54,947
Handle         Handle:44,559  --Handle is increasing slowly
Pen            Pen:53,378   
Pen            Pen:54,915     --Pen is increasing every second by 522. 

应用程序的主窗口将始终显示在屏幕上。

更新2:

pen、oldPen Bursh 和 oldBursh 在基类中声明。它们在以下过程中每次都被分配,并且该过程在整个程序中用于在 TForm 上绘制元素,如圆形、多边形、正方形、线等。

procedure TMakerGraphic.SaveCanvas;
begin
  oldPen.Assign(myForm.Canvas.Pen);
  oldBrush.Assign(myForm.Canvas.Brush);
  myForm.Canvas.Pen.Assign(Pen);
  myForm.Canvas.Brush.Assign(Brush);
end;

procedure TMakerGraphic.RestoreCanvas;
begin
  myForm.Canvas.Pen.Assign(oldPen);
  myForm.Canvas.Brush.Assign(oldBrush);
end;

释放这些变量的唯一时间是删除 TForm 上的元素时,如下面的 Free 过程所示。

destructor TMakerGraphic.Free;
begin
  Pen.Free;
  Brush.Free;
  oldPen.Free;
  oldBrush.Free;
  inherited Free;
end;

那么,这是否意味着我的应用程序正在泄漏内存?

任何意见将不胜感激。谢谢。

【问题讨论】:

  • 示例源代码会很有用。另外,我为你添加了delphi标签。
  • 我希望可以,但我什至不知道在哪里查看我的代码。
  • 这不是内存泄漏。这是资源泄漏。
  • @David Heffernan:好的。我认为内存泄漏是一个通用术语,其中包括资源泄漏。资源不是每次创建都分配内存吗?
  • @user639464:由于钢笔和画笔丢失,您可以在创建/分配钢笔或画笔的位置以及使用它们绘制的位置发布代码。

标签: delphi memory-leaks


【解决方案1】:

Pen 和 Brush 的实例似乎没有正确释放。

如果你使用的是TCanvas内置的绘图程序,请使用

Canvas.Pen.Assign(anotherPen)

填写新笔。

如果您通过 IGDIPlus 使用 gdiplus.dll,则每个绘图过程将采用 IGPPenIGPBrush 的参数。因此,要么将要传递的变量声明为IGPPen/IGPBrush;或将它们声明为TGPPen/TGPBrush,然后将它们声明为free

================= 临时 示例源代码空间 ==========

我认为 OP 给出的以下代码不会导致内存/资源泄漏。

    unit Unit1;

    interface

    uses
      Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
      Dialogs;

    type
      TForm1 = class(TForm)
        procedure FormCreate(Sender: TObject);
      private
        { Private declarations }
        currPen, prevPen: TPen;
        currBrush, prevBrush: TBrush;

        procedure FormPaint(Sender: TObject);
        procedure FormDestroy(Sender: TObject);

        procedure SaveCanvas;
        procedure RestoreCanvas;

      public
        { Public declarations }
      end;

    var
      Form1: TForm1;

    implementation

    {$R *.dfm}

    procedure TForm1.FormCreate(Sender: TObject);
    begin
      currPen := TPen.Create;
      prevPen := TPen.Create;

      currBrush := TBrush.Create;
      prevBrush := TBrush.Create;

      Self.OnPaint := Self.FormPaint;
      Self.OnDestroy := Self.FormDestroy;
    end;

    procedure TForm1.FormPaint(Sender: TObject);
    begin
      SaveCanvas;
      RestoreCanvas;
    end;

    procedure TForm1.FormDestroy(Sender: TObject);
    begin
      prevPen.Free;
      prevBrush.Free;
      currPen.Free;
      currBrush.free;
    end;

    procedure TForm1.SaveCanvas;
    begin
      prevPen.Assign(Self.Canvas.Pen);
      prevBrush.Assign(Self.Canvas.Brush);
      Self.Canvas.Pen.Assign(currPen);
      Self.Canvas.Brush.Assign(currBrush);
    end;

    procedure TForm1.RestoreCanvas;
    begin
      Self.Canvas.Pen.Assign(prevPen);
      Self.Canvas.Brush.Assign(prevBrush);
    end;

    end.

【讨论】:

  • 我确实花时间实现了您的基本代码并在 AQTime 中运行它。它没有显示任何正在添加或获取的资源。也许我以错误的方式查看 AQTime 结果。我相信 AQTime 显示的是已分配和释放的资源总量,不一定会泄漏资源。如果我错了,请纠正我。
  • @user639464:关于如何解读AQTime的结果,我想你会从他们的支持中得到最满意的结果。但是如果你的客户仍然有同样的崩溃问题,你最好再问一次,把问题放在问题的主题上。很抱歉没有提供帮助。
猜你喜欢
  • 2013-12-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-07-17
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多