为什么我的内存用的越来越多,最后Out Of Memory?谁有过相似的情况?(200分)

  • 主题发起人 主题发起人 小羽
  • 开始时间 开始时间

小羽

Unregistered / Unconfirmed
GUEST, unregistred user!
我在定时器中,开始类Create,最后类Free,但是内存越用越多,最后死掉了,谁知道是怎么回事吗?
UP者有分!!!!!!!
 
你的内存没有释放,你不断的create就不断申请内存,直到你的内存用完,看来你的FREE有问题。
 
DELPHI本身的问题,你用FREE或DESTROY都会的。
方法:系统开始CREATE一次,调用时用SHOW和HIDE,结束时再FREE,
 
最好用Release,不要用Free
因为Release等所有窗体的事件代码执行完成后才释放窗体。
建议在不要在定时器中Create、Free窗体,在定时器所在的窗体的
OnCreate中创建窗体,在OnClose中Release窗体。
 
谢谢高小五,真是高,问题好像解决了,我再试一下,不行再问大家。谢谢
 
对不起,刚才高兴得太早了,如果把release放在定时器中,则定时器不再动了,放在onclose中那么,定时器中的程序还在运算,内存使用还在不断增长,还是不能解决问题。
 
把RELEASE放在窗体的CLOSE事件中试试。
 
你是不是creat了很多个。我用free的窗体就没问题(我开了creat个窗口)。是不是你的creat用的
太多。还没show又creat了。当然就没有free了
 
你CREATE的是哪个类?我前段时间做了一个程序,也是在定时器中不断的CREATE ADO,每次都释放了,但是还是存在内存泄漏。
后来改用BDE就没有问题了。王寒松和我都做过测试,ADO确实存在内存泄漏,其他的也许有这样的问题。
建议解决方法,避免重复创建某个对象,最好只创建一次,定时器触发时只是改变操作或者其属性,程序退出时FREE掉就可以了。
以上愚见,仅供参考。
 
对于内存溢出的问题,一般是把栈内存打暴才造成的,所以一般涉及到大内存再利用的情况,
一盘把程序申请的内存放在堆中(在某种意义上:你可以把栈理解为存放局部变量的地方,堆理解为存放全局
变量的地方),例如在局部变量中声明一个0。。5000000的char型数组,那么你在
赋值,然后zeromemory ,这样的过程2000各来回就有可能打包缓冲区。然后你把它放在全局变量中,
只要注意按时zeromemory即可。
这只是一个不大真确的举例,但对你在设计程序时可能有所帮助。
上面你说的情况一定要在timetimer这个过程(和循环过程【内】)中释放类,否则就可能
有内存泄漏。
 
我再timer结束后都free了,但是还是不行,难道create一个类后就不能再create别的类了吗?费要等到着各类free后才行吗?
 
可能是你的timer里面的代码递归或死循环了,把你的代码贴出来吧
 
按理说,在create之后任何时间都是可以free的。但是如果create的太多,而又不及时释放,就算你的
做法都是对的,但是内存还是会被耗光的。
所以,假若你要create n个类什么的,就一定要在程序中记清他们的,然后在关闭程序时释放。如你要create的
类只在timetimer中使用,那么最好在timetimer的begin end之间free,如create的类要在timetimer外
使用,那么要在用完后就要free,无论如何,在程序关闭时或在所有的动作完成后再来照顾它
都不是一个好习惯。
无论如何,“跟近”它才是最保守的最好的。
实在搞不定,就贴代码出来把。如涉及到公司机密,就变动一下代码贴出来。
 
好请大家帮我看看。
unit realcaculate;

interface

uses
Windows, Messages, SysUtils, Variants, Classes, Graphics, Controls, Forms,
Dialogs, ExtCtrls,[blue]lycfluent,lyctem,qigang,gyrotor,zhyarotor;自己的PAS每个里面有一个类,有的还有FORM应该不影响把。[/blue]


type
TrealcaculateForm = class(TForm)
Timer1: TTimer;
procedure Timer1Timer(Sender: TObject);
procedure FormCreate(Sender: TObject);
procedure FormClose(Sender: TObject; var Action: TCloseAction);
private
{ Private declarations }
public
{ Public declarations }
// zhyarotor:Trotormid;
// qigang:Tqigang;

end;

var
// gyrotor1:Trotor;
realcaculateForm: TrealcaculateForm;
liu:array[0..27] of real;
tjT,lowT1,lowT2,lowT3,lowT4,lowT5,lowT6,lowT7:real;
implementation
uses fuzhi[red];//实施提供变量的FORM.[/red]

{$R *.dfm}

procedure TrealcaculateForm.Timer1Timer(Sender: TObject);
var
huire:Thuire;
turbine:Tturbine;
gyrotor1:Trotor;
zhyarotor:Trotormid;
qigang:Tqigang;
ii:integer;
x:integer;

begin

huire:=Thuire.Create;
huire:=Thuire.init;
turbine:=Tturbine.Create;
turbine:=Tturbine.init(3000,27,0.005,3,0.1,0.1,0.05,zhenkong,0,1.4);
//gyrotor1:=Trotor.Create;
//zhyarotor:=Trotormid.Create;
qigang:=Tqigang.create;
qigang.init;
huire.setD0(dd0);
huire.setxiaoliuliang(xiaoqijiF);
///////////////

huire.Free;
turbine.Free;
gyrotor1.Free;
zhyarotor.Free;
qigang.Free;

end;
end;


procedure TrealcaculateForm.FormCreate(Sender: TObject);
begin
qigang:=Tqigang.Create;
qigang.init;
gyrotor1:=Trotor.Create;
gyrotor1.rotorT;
zhyarotor:=Trotormid.Create;
zhyarotor.rotorMidT;
end;

procedure TrealcaculateForm.FormClose(Sender: TObject;
var Action: TCloseAction);
begin
RELEASE;
end;

end.
[red]////////////////////不管怎么安排累得CREATE,FREE的位置内存还是不断增长。[/red]
 
我你定义变量的问题,你只定义了一个变量,每次都是Create这个实例,实际上,上一次Create的没有释放,下一次Create的时候使用了同一个变量,则上一次Create的类实例已经没有办法再使用了,
但还在内存中,而且已经没有有办法释放了,而且你释放的时候也只能释放一次,因为你只有一个变量.
你可以试试下面的方法:

每次Create后把它放进一个TList实例中,释放的时候再把TList的每个节点取出来强制转换成类再释放.
 
用这种方式试试看:
procedure TrealcaculateForm.Timer1Timer(Sender: TObject);
var
huire:Thuire;
begin
try
huire:=Thuire.Create;
except
huire.free;
application.ProcessMessages
end;
end;
把你的代码放到try 中,释放过程写到except里,最后写上application.ProcessMessages
 
代码改为:
public
{ Public declarations }
end;
var
realcaculateForm : TrealcaculateForm;
zhyarotor : Trotormid;
zhyarotor : Trotormid;
qigang : Tqigang;
。。。。。。。
from。create
begin
//书写create及初始化语句
end;

timer。tome1timer
begin
//书写类应用语句(此处不需create)
end;

form。FormCloseQuery;
begin
//free
end;

然后在窗体建立时进行create,并进行初始化。然后在timetimer中不需释放,
在窗体关闭时释放即可。
我看了一下,你的目的只是需要了解当前设备状态,所以在程序建立时只用create
并初始化各个自建的类一次即可,然后在timetimer中分别对器进行状态传递,然后再利用结果
即可。
起始你并不需要不停的create就行。另外检查你的类中有没有char 或 各个容易引起
内存溢出的数组。

 
你的代码写的可真。。。。嘻
 
哈哈,不好意思,刚写还没改呢。。。[:D]
 
可能的原因:你 Timer的时间间隔过短,Timer1Timer(Sender: TObject);还没运行完,
下一次的Timer又到了,这是代码重入问题。所以应该加入代码防止重入
var
Busy: Boolean = false;

procedure TrealcaculateForm.Timer1Timer(Sender: TObject);
begin
if Busy then Exit;
Busy:= True;
try
// 你的代码

finally
Busy:= False;
end;
end;

 
后退
顶部