请指教,关于ontime事件中的内存释放问题(50分)

  • 主题发起人 主题发起人 飞翔鸟
  • 开始时间 开始时间

飞翔鸟

Unregistered / Unconfirmed
GUEST, unregistred user!
在timer控件的ontime事件中用qurey和table控件多次打开和关闭数据库,并对其进行操作,结果发现程序运行后,每触发一次ontime事件,程序所耗内存增加一固定值,在每次ontime事件结束之前已经close所有qurey和table控件,并且已释放所用变量,为什么程序所占内存还会不断增加?请各位高手多多指教!
 
g

interval是多少?
 
这样,你把你onTimer事件里面的所有代码全部抽出来单独执行一下,看看是否
还会有内存泄漏.如果还有,说明是代码的问题,如果没有,说明是timer的问题.
 
谢谢cakk的建议!单独执行,问题仍然存在,能谈谈qurey和table控件如何使用内存吗?
 
把代码贴出来吧.

 
限于篇幅,贴出部分代码,请指正!
procedure TForm_main.Timer1Timer(Sender: TObject);
var
//t:integer;
F:Textfile;
txt:string;
v_qh,v_sj,v_service,v_code,v_tel,v_cardno,v_cs1,v_cs2,v_cr,v_temp,v_filename,v_sent:string;
tempint:integer;
i:integer;
v_dwmc,v_hbrq,v_hbtime,v_hbrecord,v_hberror:string;

begin




//time control
timer1.Enabled:=false;

//date and time control
mydate:=datetostr(date);
mytime:=timetostr(now);
if (mydate=DateTime.enddate ) and (mytime[1]=DateTime.endtime[1]) and (mytime[2]=DateTime.endtime[2]) then
begin
application.Terminate;
end;

if (mydate=DateTime.startdate ) and (mytime[1]=DateTime.starttime[1]) and (mytime[2]=DateTime.starttime[2]) then
begin
start:=true;
end;

if start then
begin
//init var of 99999ctr.dbf
for i:=1 to 15 do v_errcount:=0;
for i:=1 to 15 do v_reccount:=0;

//empty our db

//empty 99999.dbf hn
with Query_init do
begin
close;
SQL.clear;
SQL.Add('delete');
SQL.Add('FROM "99999.dbf"');
//execsql;
end;
try
Query_init.execsql;
PackDbaseTable(Table_99999);
except
on EDatabaseError do//if 99999.dbf not exists
begin
Myinfo:='很抱歉,数据库99999.dbf不存在,程序即将关闭!';
Application.OnException := AppException;

end;
end; //of except

//empty yy99999.dbf 730
with Query_init do
begin
close;
SQL.clear;
SQL.Add('delete');
SQL.Add('FROM "yy99999.dbf"');
//execsql;
end;
try
Query_init.execsql;
PackDbaseTable(Table_yy99999);
except
on EDatabaseError do//if yy99999.dbf not exists
begin
Myinfo:='很抱歉,数据库yy99999.dbf不存在,程序即将关闭!';
Application.OnException := AppException;

end;
end; //of except

Query_init.close;

//init error log txt
txt :=DateTimeToStr(Now);;
assignfile( F,'c:/168/logerror.txt');
rewrite(F);
writeln(F,txt);
closefile(F) ;


//import their db to our db

//import c:/168/yy/99999/yy99999.dbf to 16899999/yy99999.dbf 730
if yyexist then
begin

with Query_outinit do
begin
close;
SQL.clear;
SQL.Add('SELECT DISTINCT "yy99999.dbf"."cardno",tel');
SQL.Add('FROM "c:/168/yy/99999/yy99999.dbf"');
//exeyyql;
end;
try
Query_outinit.open;
except
on EDatabaseError do //if yz99999.dbf not exists
begin
{write error log}
txt :='数据库yy99999.dbf正在被上传文件覆盖,该数据库暂时无法合并!';
assignfile( F,'c:/168/logerror.txt');
if FileExists( 'c:/168/logerror.txt')then
begin
Append(F)
end else
begin
rewrite(F);
end;
writeln(F,txt);
closefile(F);
Application.OnException := outAppException;
v_errcount[2]:=v_errcount[2]+1;
end;
end; //of except

Query_outinit.first;
while not Query_outinit.eof do
begin
v_qh:='730';

v_temp:=trim( (Query_outinit.findfield('tel').asstring));
if length(v_temp)=11 then
begin
v_tel:= v_temp;
//StrLCopy(v_tel, vtemp, 11);
end;//of if
if length(v_temp)=7 then
begin
v_tel:='0'+v_qh+v_temp;
end;//of if
if (length(v_temp)<>7) and (length(v_temp)<>11) then
begin
v_tel:=' ';
end;//of if

v_temp:=trim( Query_outinit.findfield('cardno').asstring);
if length(v_temp)=15 then
begin
v_cardno:= v_temp+' ';
//StrLCopy(v_tel, vtemp, 11);
end;//of if
if (length(v_temp)<>15) then
begin
v_cardno:=' ';
end;//of if


with Query_init do
begin
close;
RequestLive :=true;
SQL.clear;
SQL.Add('SELECT "yy99999.dbf"."qh", code, tel,cardno,field2');
SQL.Add('FROM "yy99999.dbf"');
open;
end;

Query_init.append;
Query_init.Edit ;
Query_init.Findfield('qh').asstring:=v_qh;
Query_init.Findfield('code').asstring:=c_code;
Query_init.Findfield('tel').asstring:=v_tel;
Query_init.Findfield('cardno').asstring:=v_cardno;
Query_init.Findfield('field2').asstring:=v_field2;
Query_init.Post ;

Query_outinit.next;
end;// of while
yyexist:=false;
end; //of if



//empty 99999.dbf ---------not done

//hebing our db to 99999.dbf

//hebin yy99999.dbf to 99999.dbf
with Query_init do
begin
close;
SQL.clear;
SQL.Add('insert into "99999.dbf" ("99999.dbf"."code", tel,cardno,cs1)');
SQL.Add('SELECT "yy99999.dbf"."code", tel,cardno,field2');
SQL.Add('FROM "yy99999.dbf"');
//exeyyql;
end;
try
Query_init.execsql;
except
on EDatabaseError do //if yy99999.dbf not exists
begin
Myinfo:='很抱歉,数据库yy99999.dbf不存在或者数据库字段名错误,程序即将关闭!';
Application.OnException := AppException;
end;
end; //of except


//set default value to other fields in 99999.dbf
with Query_init do
begin
close;
RequestLive :=true;
SQL.clear;
SQL.Add('SELECT "99999.dbf"."sj", service, cs2,cr');
SQL.Add('FROM "99999.dbf"');
open;
end;
Randomize;
Query_init.first;
while not Query_init.eof do
begin
Query_init.Edit ;
repeat
tempint:=Random(c_sj)+1;
until (tempint>=10000000);
v_sj:=inttostr(tempint);
Query_init.Findfield('sj').asstring:=v_sj;
Query_init.Findfield('service').asstring:=c_service;
Query_init.Findfield('cs2').asstring:=c_cs2;
Query_init.Findfield('cr').asstring:=c_cr;
Query_init.Post ;
Query_init.next;
end;


//copy 99999.dbf to 99999.db
with Query_init do
begin
close;
SQL.clear;
SQL.Add('SELECT "99999.dbf"."code", tel,cardno,cs1,cs2,cr,sj,service');
SQL.Add('FROM "99999.dbf"');
end;
try
Query_init.open;
except
on EDatabaseError do //if 99999.dbf not exists
begin
Myinfo:='很抱歉,数据库99999.dbf不存在或者数据库字段名错误,程序即将关闭!';
Application.OnException := AppException;
end;
end; //of except

Query_init.first;
with Table_99999db do
begin
close;
open;
end;
while not Query_init.eof do
begin
v_cardno:=Query_init.Findfield('cardno').asstring;
v_tel:=Query_init.Findfield('tel').asstring;
v_code:=Query_init.Findfield('code').asstring;
if not Table_99999db.FindKey ( [v_code,v_tel,v_cardno]) then
begin

Table_99999db.Append ;
Table_99999db.Edit;
Table_99999db.FindField ('code').asstring:= Query_init.FindField ('code').asstring;
Table_99999db.FindField ('tel').asstring:= Query_init.FindField ('tel').asstring;
Table_99999db.FindField ('cardno').asstring:= Query_init.FindField ('cardno').asstring;
Table_99999db.FindField ('cs1').asstring:= Query_init.FindField ('cs1').asstring;
Table_99999db.FindField ('cs2').asstring:= Query_init.FindField ('cs2').asstring;
Table_99999db.FindField ('cr').asstring:= Query_init.FindField ('cr').asstring;
Table_99999db.FindField ('sj').asstring:= Query_init.FindField ('sj').asstring;
Table_99999db.FindField ('service').asstring:= Query_init.FindField ('service').asstring;
if (Table_99999db.Findfield('sent').asstring<>'1') and (Table_99999db.Findfield('sent').asstring<>'0') then
begin
Table_99999db.Findfield('sent').asstring:='0';
end;
Table_99999db.post;
end; // of if

Query_init.next;
end;
Table_99999db.close;



//copy 99999.db to file ABCDEFGH.XYZ

//v_filename:='c:/168/'+v_temp;
v_temp:=datetostr(date)+timetostr(now);
if v_temp[13]=':' then v_filename:=v_temp[6]+v_temp[7]+v_temp[9]+v_temp[10]+v_temp[11]+v_temp[12]+v_temp[14]+v_temp[15]+'.'+v_temp[17]+v_temp[18]+inttostr(random(10));
if v_temp[12]=':' then v_filename:=v_temp[6]+v_temp[7]+v_temp[9]+v_temp[10]+'0'+v_temp[11]+v_temp[13]+v_temp[14]+'.'+v_temp[16]+v_temp[17]+inttostr(random(10));

{if MessageDlg(v_filename,mtInformation,[mbOk],0)=mrOk then
begin
end;}

with Table_99999db do
begin
close;
open;
end;

Table_99999db.first;
while not Table_99999db.eof do
begin
v_sent:=Table_99999db.Findfield('sent').asstring;
if v_sent='0' then
begin

v_sj:=Table_99999db.Findfield('sj').asstring;
v_service:=Table_99999db.Findfield('service').asstring;

v_code:=Table_99999db.Findfield('code').asstring+' ';
v_tel:=Table_99999db.Findfield('tel').asstring;
if length(v_tel)<11 then v_tel:=' ' ;
v_cardno:=Table_99999db.Findfield('cardno').asstring;
if length(v_cardno)=15 then v_cardno:=v_cardno+' ' ;
if length(v_cardno)<15 then v_cardno:=' ';
v_cs1:=Table_99999db.Findfield('cs1').asstring+' ';
v_cs2:=Table_99999db.Findfield('cs2').asstring+' ';
v_cr:=Table_99999db.Findfield('cr').asstring+' ';

assignfile( F,'c:/168/'+v_filename);
if FileExists( 'c:/168/'+v_filename)then
begin
Append(F)
end else
begin
rewrite(F);
end;


write(F ,v_sj);
write(F ,v_service);
write(F ,v_code);
write(F ,v_tel);
write(F ,v_cardno);
write(F ,v_cs1);
write(F ,v_cs2);
writeln(F,v_cr);
closefile(F);


Table_99999db.Edit ;
Table_99999db.Findfield('sent').asstring:='1';
Table_99999db.Post ;
end;//of if
Table_99999db.next;
end; //of while

// if c:/168/ABCDEFGH.XYZ exists copy c:/168/ABCDEFGH.XYZ to c:/168cen/outbox/ABCDEFGH.XYZ
if FileExists('c:/168/'+v_filename) then MoveFile(PChar('c:/168/'+v_filename),PChar('c:/168cen/outbox/'+v_filename) );

//set value to the var xxrecord of 99999ctr.dbf

//set rcordercount of 99999.db to var allrecord
with Table_99999db do
begin
close;
open;
end;
v_reccount[1]:=v_reccount[1]+ Table_99999db.RecordCount;
Table_99999db.close;

//set rcordercount of yy99999.dbf to var yyrecord
with Query_init do
begin
close;
RequestLive :=true;
SQL.clear;
SQL.Add('SELECT "yy99999.dbf"."qh"');
SQL.Add('FROM "yy99999.dbf"');
open;
end;
v_reccount[2]:=v_reccount[2]+ Query_init.RecordCount;

//set recorder value to 99999ctr.dbf
with Query_init do
begin
close;
RequestLive :=true;
SQL.clear;
SQL.Add('SELECT "99999ctr.dbf"."DWMC", HBRQ, HBTIME,HBRECORD,HBERROR');
SQL.Add('FROM "99999ctr.dbf"');
open;
end;
i:=1;
while (i<=15) do
begin
Query_init.append;
Query_init.Edit ;
Query_init.Findfield('DWMC').asstring:=c_dwmc;
Query_init.Findfield('HBRQ').asstring:=datetostr(date);
Query_init.Findfield('HBTIME').asstring:=timetostr(now);
Query_init.Findfield('HBRECORD').asstring:= inttostr(v_reccount mod 100000000);
Query_init.Findfield('HBERROR').asstring:=inttostr(v_errcount mod 100000000);;
Query_init.Post ;
i:=i+1;
end;


//copy 99999ctr.dbf to file c:/168/99999.txt
//init error log txt
txt :=DateTimeToStr(Now);;
assignfile( F,'c:/168/99999.txt');
rewrite(F);
writeln(F,txt);
write(F ,'单位名称 ');
write(F ,'合并日期 ');
write(F ,'合并时间 ');
write(F ,'已合并记录数 ');
writeln(F ,'合并出错次数');
closefile(F) ;

with Query_99999ctr do
begin
close;
SQL.clear;
SQL.Add('SELECT "99999ctr.dbf"."DWMC", HBRQ, HBTIME,HBRECORD,HBERROR');
SQL.Add('FROM "99999ctr.dbf"');
open;
end;
Query_99999ctr.first;
i:=1;
while not Query_99999ctr.eof do
begin
//v_dwmc,v_hbrq,v_hbtime,v_hbrecord,v_hberror
v_dwmc:=Query_99999ctr.Findfield('dwmc').asstring+' ';
if (i=12) or (i=13) then v_dwmc:=Query_99999ctr.Findfield('dwmc').asstring+' ';
v_hbrq:=Query_99999ctr.Findfield('hbrq').asstring+' ';
v_hbtime:=Query_99999ctr.Findfield('hbtime').asstring+' ';
v_hbrecord:=Query_99999ctr.Findfield('HBRECORD').asstring+' ';
if (i=1) then v_hbrecord:=Query_99999ctr.Findfield('HBRECORD').asstring+' ';
v_hberror:=Query_99999ctr.Findfield('HBERROR').asstring;

assignfile( F,'c:/168/99999.txt');
if FileExists( 'c:/168/99999.txt')then
begin
Append(F)
end else
begin
rewrite(F);
end;


write(F ,v_dwmc);
write(F ,v_hbrq);
write(F ,v_hbtime);
write(F ,v_hbrecord);
writeln(F,v_hberror);
closefile(F);


Query_99999ctr.next;
i:=i+1;
end;

//dbgrid show 99999ctr.dbf
with Query_99999ctr do
begin
close;
SQL.clear;
SQL.Add('SELECT "99999ctr.dbf"."DWMC", HBRQ, HBTIME,HBRECORD,HBERROR');
SQL.Add('FROM "99999ctr.dbf"');
//execsql;
end;
try
Query_99999ctr.DisableConstraints ;
try
Query_99999ctr.Open;
DataSource1.Enabled :=true;
//s:='当前成功提取数据库记录共'+inttostr(Query_Out.RecordCount) +'条!';
//Label1.Caption :=s;
//Panel3.caption:=s;
finally
Query_99999ctr.EnableConstraints ;
end;
except
on EDatabaseError do //if 99999ctr.dbf not exists
begin
showMessage('很抱歉,数据库99999ctr.dbf不存在或者数据库字段名错误,程序即将关闭!');
application.Terminate;;
end;
end; //of except

// CLOSE all dateset except Query_99999ctr
Query_init.close;
Query_outinit.close;
Table_99999.Close;
Table_99999ctr.Close;
Table_yy99999.Close;
Table_cs99999.Close;
Table_xt99999.Close;
Table_zz99999.Close;
Table_hy99999.Close;
Table_cz99999.Close;
Table_cd99999.Close;
Table_yi99999.Close;
Table_ld99999.Close;
Table_sy99999.Close;
Table_zh99999.Close;
Table_zj99999.Close;
Table_hh99999.Close;
Table_zz99999.Close;

{
// free all dateset except Query_99999ctr
Query_init.free;
Query_outinit.free;
Table_99999.free;
Table_99999ctr.free;
Table_yy99999.free;
Table_cs99999.free;
Table_xt99999.free;
Table_zz99999.free;
Table_hy99999.free;
Table_cz99999.free;
Table_cd99999.free;
Table_yi99999.free;
Table_ld99999.free;
Table_sy99999.free;
Table_zh99999.free;
Table_zj99999.free;
Table_hh99999.free;
Table_zz99999.free;
}
//free local var
txt:='';
v_qh:='';
v_sj:='';
v_service:='';
v_code:='';
v_tel:='';
v_cardno:='';
v_cs1:='';
v_cs2:='';
v_cr:='';
v_temp:='';
v_filename:='';
v_sent:='';
v_dwmc:='';
v_hbrq:='';
v_hbtime:='';
v_hbrecord:='';
v_hberror:='';
i:=1;
tempint:=1;

end;//of if start

//time control
timer1.Enabled:=true;

end;
 
我的老天! 我要死了.

我只能建议你:
1.把代码拆成小的片断,分别调试,逐步缩小范围;
2.或者,你的Application.OnException := AppException;是什么意思?
会不会漏掉了某些异常? 而正是这些异常造成了内存泄漏?
 
timer控件不能多用,很耗资源。你的talbe close后应该没有资源占用。
估计是程序问题。
agree cakk 分别调试!!!
 
TO CAKK:
呵呵,看傻了吧(me too) :>
to 飞翔鸟:
建议你在notpad上删除一切有关数据库的执行操作,再执行一下再查.
 建议使用一个Tdatabase控件,将所有Table定向到它上面,否则每次
 程序会动态生成Tdatabase,问题会不会在这里.


 
用您提议的分块调试的方法发现:使用select语句并open执行时,若数据库很规范(字段名、长度、记录的唯一性)程序占用内存不变,当数据库不太规范(字段名正确,但长度不合标准,库中重复记录多,则内存不断增加;如执行以下代码:
with Query_outinit do
begin
close;
SQL.clear;
SQL.Add('SELECT "yy99999.dbf"."cardno",tel');
SQL.Add('FROM "c:/168/yy/99999/yy99999.dbf"');
//execsql;
end;
try
Query_outinit.open;
yyexist:=true;
except
on EDatabaseError do //if yy99999.dbf not exists
begin
{write error log}
txt :='数据库yy99999.dbf不存在,或者字段cardno与字段tel存在命名错误,该数据库无法合并!';
assignfile( F,'c:/168/logerror.txt');
if FileExists( 'c:/168/logerror.txt')then
begin
Append(F)
end else
begin
rewrite(F);
end;
writeln(F,txt);
closefile(F);
Application.OnException := outAppException;
v_errcount[2]:=v_errcount[2]+1;
end;
end; //of except
请指教!
 
谢谢,新年快乐!
 
后退
顶部