我真的要拿刀砍了delphi(100分)

  • 主题发起人 主题发起人 smallmoneybags
  • 开始时间 开始时间
S

smallmoneybags

Unregistered / Unconfirmed
GUEST, unregistred user!
这个鸟delphi,气死我了。内存释放的问题

问题是这样的。我有两个窗体,

form1, 主窗体,form2在projects设为手工创建 。

在Form1,上放了一个button1, 在implea..下引用form2.

var
Form1: TForm1;

implementation

uses Unit2;

{$R *.dfm}

procedure TForm1.Button1Click(Sender: TObject);
begin
if not Assigned(Form2) then
Form2:=TForm2.Create(Self);
Form2.Show;
//第二次Show的时候Create就不会执行,但是实际上Form2已经不存在了,所以Form2.Show
end;

//下面是form2的代码


{$R *.dfm}

procedure TForm2.Button1Click(Sender: TObject);
begin
Close;
end;

procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
begin
action:=cafree;
FORM2:=NIL;
end;

end.


另外我在form2上放了一张600*800的bmp格式图象,
当form1第一次调用 form2的时候,占用了500K的内存, 
在关闭form2窗体后,这个图象资源根本就没有释放。只是放了十几k (如果没有图象也是一样,就是一个空窗体), 第二次调用的时候好象资源没占多少。

但是当主窗体关闭后,内存又复位了。

form2关闭后怎样把form2彻底.

不信的大家可以自己做个实验,就两个窗体。
 
功力不够, 可以理解你的心情。

form2.free只是释放了form2所指向的实例(可以理解为form2本身是个指针,内容指向一块内存, 那块内存里存放了form2实例的具体内容)
form2本是的值并未清空。 而if assigned(form2)其实就等于 if form2 <> nil
所以第二次调用时会出错, 因为form2这时仍然指向一块已经被释放掉了的内存。 当然不等于nil

第二个问题:
第一次内存增加只是因为当时你程序的堆空间不够, delphi的内存管理机制向windows申请了一块内存。 而这块内存就由delphi帮你管起来了。 form2.free时只是在堆中标记这块内存可用而已, 但并未返回windows。这样当程序再次需要内存时不必向windows再申请了, 直接就使用堆中的空内存就可以了。 这样效率会提高很多。

所以你的两个问题都不能称之为问题。

最多半年后, 你就会觉得提这两个问题很幼稚了。
 
to Another_eYes,
我已经调用了.free, nil 应该彻底清空, 对吧。 为什么没有反回给windows.

下面是我的测试数据。真见鬼。

起始空闲内存 214,996/kb
点击运行程序显示窗体214,308/kb (就一个窗体+一个button)

点击button1弹出form2,208,196/kb

点击form2的关闭按钮后 213.994 //没有回到起始的214.308

再次点击Form1的button1 启动form2.再点击form2的关闭钮按.

     显示的内存为213.994 //

关闭主程序,214,856 //比运行前少了几十k

 
而if assigned(form2)其实就等于 if form2 <> nil
所以第二次调用时会出错,

我在form2没关闭的情况下, 再次点击form1的button, 为什么没有报错, 你这话是啥意思。

 
我还要说明一下,这个程序不是在调试环境下 运行的。 是单独的.exe文件运行。 
to
Another_eYes,
你所说的是由delphi来管理的。 但我不在调试环境下运行的.
 
看到你在csdn上的相同帖子了。
我真的要拿刀砍了csdn,又进不去了!
 
试试
procedure TForm1.Button1Click(Sender: TObject);
begin
With TForm2.Create(Self) Do
Begin
ShowModal;
Free;
End;
End;

//下面是form2的代码


{$R *.dfm}

procedure TForm2.Button1Click(Sender: TObject);
begin
Close;
end;

procedure TForm2.FormClose(Sender: TObject; var Action: TCloseAction);
begin
action:=cafree;
End;

 
说完整点是delphi在您程序中嵌入的内存管理代码来管理的。 觉得拗口, 所以就简化成delphi帮您管了。
呵呵
 
to liujunzhang 不管是showmodl, 还是show都没释放。
 
to Another_eYes 你向是对三岁小孩子说的话,


说完整点是delphi在您程序中嵌入的内存管理代码来管理的。 觉得拗口, 所以就简化成delphi帮您管了。

那为什么我主窗体关闭后,还少了几十k, 
 
谢谢Another_eYes, 如果没有意见,待会结贴。
 
多人接受答案了。
 
action:=cafree; //只对mdi子窗口有用
FORM2:=NIL; //只改变变量指针,实列并没有释放。

所以如果你的窗口是mdi子窗口,只要:action:=cafree否则要用free;
 
不会吧, 都没有解决问题就结贴了?
 
后退
顶部