如何释放内存?(附源码)(30分)

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

samxu

Unregistered / Unconfirmed
GUEST, unregistred user!
DLL中的函数如下:
function GetImage(bmpname:string):TBitmap;
begin
result := TBitmap.Create;
result.LoadFromResourceName(HInstance,bmpname);
end;
然后我在主程序中调用:
for i:=1 to 100
begin
img[n]:=Timage.creat(self);
img[N].Picture.Bitmap := GetImage('imgfilename');
end;
发觉内存暴长,在98下面,资源由90%狂降到30%,请高手指点迷津,谢谢!


 
程序结束的时候得
for i:=1 to 100
begin
img[N].Picture.Bitmap.free;
img[n].free
end;
 
把你创建的free掉
 
申请上百个位图,而且都有内容,系统当然受不了,没垮就不错了。
就算是一个位图,如果你把Width和Height设大一点,系统都觉得难受。
 
如果改成要用图的时候再get出来就不会这样子了,用完了再free.
 
强烈同意Huzzz [:D]
 
TO:Adnil
程序结束的时候当然可以FREE掉的。
TO:Huzzz
如果我不调用函数,而是先在FORM上放一个图片TestImg,然后用
for i:=1 to 100
begin
img[n]:=Timage.creat(self);
img[N].Picture.Bitmap := TestImg.Picture.Bitmap ;
end;
就不会出现内存暴长的情况,图片我在程序运行的时候要显示的,不可以FREE掉的,
请问如何解决?谢谢
 
那就怪了,我去试试看
 
//看一下原码
procedure TPicture.SetGraphic(Value: TGraphic);
var
NewGraphic: TGraphic;
begin
NewGraphic := nil;
if Value <> nil then
begin
NewGraphic := TGraphicClass(Value.ClassType).Create;
NewGraphic.Assign(Value); //在这里它复制了一份,所以你的没释放掉
NewGraphic.OnChange := Changed;
NewGraphic.OnProgress := Progress;
end;
try
FGraphic.Free;
FGraphic := NewGraphic;
Changed(Self);
except
NewGraphic.Free;
raise;
end;
end;
-------------------------------------
var B: TBitmap;

for i:=1 to 100
begin
img[n]:=Timage.creat(self);
B := GetImage('imgfilename');
try
img[N].Picture.Bitmap := B;
finally
B.Free;
end;
end;

 
property Bitmap: TBitmap read GetBitmap write SetBitmap;

procedure TPicture.SetBitmap(Value: TBitmap);
begin
SetGraphic(Value);
end;
-------------------------------------------
在img[N].Picture.Bitmap := GetImage('imgfilename');时调用的是SetGraphic



 
samxu, 我试了一下,照你的写法确实没有问题,我记得不知哪里说的,DELPHI中的位图
资源是可以共享的,8成是被共享了。你试下下面的写法,包你暴涨一把:
for n:=1 to 100 do
begin
img[n]:=Timage.create(self);
//这里稍为改大成1000X1000,系统报告“内存不足,不能完成。。。。”
//我的机子是384M内存
img[N].Picture.Bitmap.Width := 800;
img[N].Picture.Bitmap.Height := 600;
img[N].Picture.Bitmap.Canvas.Draw(0,0,TestImg.Picture.Bitmap);
//img[N].Picture.Bitmap := TestImg.Picture.Bitmap ;
end;
 
To:203010
你写得好像有点乱,能给我整理一下吗?

这程序是这样的,我在一个FORM上要显示100个同样的图片,如果在设计的时候放上去
是不会出现内存暴长的,但用我以上写的方法时就出现内存暴长,请问应该如何修改?
 
我的意思是写成这样就可以了
var B: TBitmap;

for i:=1 to 100
begin
img[n]:=Timage.creat(self);
B := GetImage('imgfilename');
try
img[N].Picture.Bitmap := B;
finally
B.Free; //放掉了
end;
end;
 
这样不行的,内存暴长和我先前的一样。我想可能是DLL中的问题
DLL中的函数:
function GetImage(bmpname:string):TBitmap;
begin
result := TBitmap.Create;
result.LoadFromResourceName(HInstance,bmpname);
end;
可能是result没有FREE掉,但RESULT如果FREE掉了,getimage时就会出错,怎么办
才好??
 
?不会吧,确实放掉了啊,你单独试一下,告我结果
var B: TBitmap;

for i:=1 to 100
begin
B := GetImage('imgfilename');
B.Free; //放掉了
end;
 
To samxu:
看了你的函数,简单的办法是不要返回TBitmap,如果只是相同的拷贝,直接返回创建了
的位图在内存中的句柄即可,如果需要不同的位图调用同一个资源获取函数,你只要在该
函数中建立一个数组返回句柄。当然,如果你的位图都很大,最好是从资源读出后先送入
临时文件,这样用的时候直接调用一次LoadFormFile即可,并及时释放掉。
另外,在有大量图形的调用中,最好先规划一下内存,争取在有限的内存中,多调入一些
图形,尤其是很频繁使用的图形。
 
function GetImage(bmpname:string):TBitmap;
begin
result := TBitmap.Create;
result.LoadFromResourceName(HInstance,bmpname);
end;
然后我在主程序中调用:
for i:=1 to 100
begin
img[n]:=Timage.creat(self);// 多余了!
img[N].Picture.Bitmap := GetImage('imgfilename');
end;
 
如果我不调用函数,而是先在FORM上放一个图片TestImg,然后用
for i:=1 to 100
begin
img[n]:=Timage.creat(self);
img[N].Picture.Bitmap := TestImg.Picture.Bitmap ;
end;
就不会出现内存暴长的情况,图片我在程序运行的时候要显示的,不可以FREE掉的,
请问如何解决?谢谢

对于以上用法,你在内存中实际上只有一个TBitmap当然内存不会暴长.只是有100个指向它的指针存在.
你的程序算法有问题,同时往内存中调用100个Bitmap,当然会内存不足,应该在所需时调用,或用数据库解决
 
我终于弄明白了,你是98,我刚才在Win2000下原样做了一遍,根本没事。
98下GDI资源、内存不够了,不要说是100个TImage,我原来的几个窗的控件太多了,
多显示几份就GDI资源不够了,然后死机,后来只有同时只显示一份了。
[:(]换个办法显示吧。
看大家有别的办法没[?]
 
NT与98在内存的处理上差别太大了
 
后退
顶部