我在Windows 7下运行使用RAD Studio XE或Delphi XE开发的应用程序。从以前的项目文件重建我的应用程序后,我一直在测试它的功能,但应用程序只能运行大约一个月左右并启动慢慢地失败。除非Windows操作系统出现故障,否则此应用程序应始终全天候运行。所以,我在应用程序上运行AQTime几个小时,并在程序运行时密切关注结果。我注意到的是这个。在其他所有内容保持不变且数量仍然存在的情况下,在资源分析中,Brush,Handle,Pen和另一个Pen的数量正在慢慢增加,特别是第二笔和Brush资源。笔的数量似乎每秒增加约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.
应用程序的主窗口将始终显示在屏幕上。
UPDATE2:
笔,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;
那么,这是否意味着我的应用程序正在泄漏内存?
任何输入都将不胜感激。谢谢。
答案 0 :(得分:0)
似乎没有正确释放Pen和Brush的实例。
如果您使用的是TCanvas的内置绘图程序,请使用
Canvas.Pen.Assign(anotherPen)
填写新笔。
如果您通过IGDIPlus使用gdiplus.dll,则每个绘图过程将采用IGPPen
或IGPBrush
的参数。因此,要么声明变量通过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.