多线程的内存释放问题,大家看看我的代码吧!等待ing ( 积分: 200 )

  • 主题发起人 主题发起人 fbyang
  • 开始时间 开始时间
F

fbyang

Unregistered / Unconfirmed
GUEST, unregistred user!
调用方法:
(transThread.Create(adcConfigConnection.ConnectionString,1) ).OnTerminate :=ThreadDone ;

ThreadDone函数只是做了线程数的更新

线程代码:
unit Uit_TransThread;
interface
uses
windows,SysUtils,Classes, Dialogs,ADODB,db, ActiveX;
type
transThread = class(TThread)
private
sMetaViewSQL,sTargetTable:String ;
sConfigConnStr,sTargetConnStr,sMetaConnStr:String ;
iTransSubjectID:integer ;
adoTargetConnection:TAdoConnection ;
adoMetaConnection,adoConfigConnection:TAdoConnection ;
cdsTargetField,adoConfig_Log,adoMetaQuery,adoTemp,adoTargetQuery:TAdoQuery ;
//thread
Destructor Destroy;
procedure TransData;
{ Private declarations }
protected
procedure Execute;
override;
public
constructor Create(ConfigConnStr:String;TransSubjectID:Integer);
end;

implementation

{ transThread }
procedure transThread.Execute;
begin
TransData ;
end;
constructor transThread.Create(ConfigConnStr:String;TransSubjectID:Integer);
begin
inherited Create(False);
CoInitialize( nil );//使用com对象必须要初始化
FreeOnTerminate := True;
iTransSubjectID := TransSubjectID ;
sConfigConnStr := ConfigConnStr ;
adoTargetConnection:=Tadoconnection.Create(nil);//动态生成的连接
adoMetaconnection := tAdoConnection.Create(nil);
adoConfigConnection := TAdoConnection.Create(nil);

adoconfigconnection.LoginPrompt :=false;
adoConfigconnection.ConnectionString := sConfigConnStr ;
adoConfigconnection.KeepConnection :=false;


adoTargetConnection.LoginPrompt :=false;
adoTargetConnection.ConnectionString := sTargetConnStr ;
adoTargetConnection.KeepConnection :=false;
adoMetaconnection.LoginPrompt :=false;
adoMetaconnection.ConnectionString := sMetaConnStr ;
adoMetaconnection.KeepConnection :=false;

adoConfig_Log := TAdoQuery.Create(nil);
adoConfig_Log.Connection := adoConfigConnection ;
adoMetaQuery := TAdoQuery.Create(nil);
adoMetaQuery.Connection := adoMetaConnection ;

adoTargetQuery := TAdoQuery.Create(nil) ;
adoTargetQuery.connection := adoTargetConnection ;

cdsTargetField := TAdoQuery.Create(nil) ;
cdsTargetField.Connection := adoConfigConnection ;
cdsTargetField.SQL.Text := 'select * from Field_comp where DS_INT_ID = ' +IntToStr(iTransSubjectID) ;//thread
cdsTargetField.Open ;//thread
adoTemp := TAdoQuery.Create(nil);
adoTemp.Connection := adoConfigConnection ;
adoTemp.SQL.text := 'select * from data_subject where DS_INT_ID = ' +IntToStr(iTransSubjectID) ;//thread
adoTemp.Open ;
sMetaViewSQL := adoTemp.fieldByName('DS_CH_MDATA').AsString ;
sTargetTable := adoTemp.fieldByName('DS_CH_TAGDATA').AsString ;
sMetaConnStr := adoTemp.fieldByName('DS_CH_METASTR').AsString ;
sTargetConnStr := adoTemp.fieldByName('DS_CH_TAGSTR').AsString ;
adotemp.Close ;


end;

destructor transThread.Destroy;
begin


cdsTargetField.Active := false ;
adoConfig_Log.Active := false ;
adoMetaQuery.Active := false ;
adoTemp.Active := false ;
adoTargetQuery.Active := false ;

//cdsTargetField.Free ;
//adoConfig_Log.Free ;
//adoMetaQuery.Free ;
//adoTemp.Free ;
//adoTargetQuery.Free ;

//cdsTargetField := nil ;
//adoConfig_Log := nil ;
//adoMetaQuery := nil ;
//adoTemp := nil ;
//adoTargetQuery := nil ;
//cdsTargetField.Destroy ;
//adoConfig_Log.Destroy ;
//adoMetaQuery.Destroy ;
//adoTemp.Destroy ;
//adoTargetQuery.Destroy ;
FreeAndNil(cdsTargetField) ;
FreeAndNil(adoConfig_Log) ;
FreeAndNil(adoMetaQuery) ;
FreeAndNil(adoTemp) ;
FreeAndNil(adoTargetQuery) ;
adoMetaConnection.Connected := false ;
adoConfigConnection.Connected := false ;
adoTargetConnection.Connected := false ;
//adoMetaConnection.Free ;
//adoConfigConnection.Free ;
//adoTargetConnection.Free ;
//adoMetaConnection.Destroy ;
//adoConfigConnection.Destroy ;
//adoTargetConnection.Destroy ;
FreeAndNil(adoMetaConnection) ;
FreeAndNil(adoConfigConnection) ;
FreeAndNil(adoTargetConnection) ;
//adoMetaConnection := nil ;
//adoConfigConnection := nil ;
//adoTargetConnection:= nil ;


CoUnInitialize;//必须使用
inherited destroy;
end;

procedure transThread.TransData;
begin
//本来有代码,这里暂时删除,因为我把这里代码注释的情况下,内存还是不断上涨
end ;

end.
 
调用方法:
(transThread.Create(adcConfigConnection.ConnectionString,1) ).OnTerminate :=ThreadDone ;

ThreadDone函数只是做了线程数的更新

线程代码:
unit Uit_TransThread;
interface
uses
windows,SysUtils,Classes, Dialogs,ADODB,db, ActiveX;
type
transThread = class(TThread)
private
sMetaViewSQL,sTargetTable:String ;
sConfigConnStr,sTargetConnStr,sMetaConnStr:String ;
iTransSubjectID:integer ;
adoTargetConnection:TAdoConnection ;
adoMetaConnection,adoConfigConnection:TAdoConnection ;
cdsTargetField,adoConfig_Log,adoMetaQuery,adoTemp,adoTargetQuery:TAdoQuery ;
//thread
Destructor Destroy;
procedure TransData;
{ Private declarations }
protected
procedure Execute;
override;
public
constructor Create(ConfigConnStr:String;TransSubjectID:Integer);
end;

implementation

{ transThread }
procedure transThread.Execute;
begin
TransData ;
end;
constructor transThread.Create(ConfigConnStr:String;TransSubjectID:Integer);
begin
inherited Create(False);
CoInitialize( nil );//使用com对象必须要初始化
FreeOnTerminate := True;
iTransSubjectID := TransSubjectID ;
sConfigConnStr := ConfigConnStr ;
adoTargetConnection:=Tadoconnection.Create(nil);//动态生成的连接
adoMetaconnection := tAdoConnection.Create(nil);
adoConfigConnection := TAdoConnection.Create(nil);

adoconfigconnection.LoginPrompt :=false;
adoConfigconnection.ConnectionString := sConfigConnStr ;
adoConfigconnection.KeepConnection :=false;


adoTargetConnection.LoginPrompt :=false;
adoTargetConnection.ConnectionString := sTargetConnStr ;
adoTargetConnection.KeepConnection :=false;
adoMetaconnection.LoginPrompt :=false;
adoMetaconnection.ConnectionString := sMetaConnStr ;
adoMetaconnection.KeepConnection :=false;

adoConfig_Log := TAdoQuery.Create(nil);
adoConfig_Log.Connection := adoConfigConnection ;
adoMetaQuery := TAdoQuery.Create(nil);
adoMetaQuery.Connection := adoMetaConnection ;

adoTargetQuery := TAdoQuery.Create(nil) ;
adoTargetQuery.connection := adoTargetConnection ;

cdsTargetField := TAdoQuery.Create(nil) ;
cdsTargetField.Connection := adoConfigConnection ;
cdsTargetField.SQL.Text := 'select * from Field_comp where DS_INT_ID = ' +IntToStr(iTransSubjectID) ;//thread
cdsTargetField.Open ;//thread
adoTemp := TAdoQuery.Create(nil);
adoTemp.Connection := adoConfigConnection ;
adoTemp.SQL.text := 'select * from data_subject where DS_INT_ID = ' +IntToStr(iTransSubjectID) ;//thread
adoTemp.Open ;
sMetaViewSQL := adoTemp.fieldByName('DS_CH_MDATA').AsString ;
sTargetTable := adoTemp.fieldByName('DS_CH_TAGDATA').AsString ;
sMetaConnStr := adoTemp.fieldByName('DS_CH_METASTR').AsString ;
sTargetConnStr := adoTemp.fieldByName('DS_CH_TAGSTR').AsString ;
adotemp.Close ;


end;

destructor transThread.Destroy;
begin


cdsTargetField.Active := false ;
adoConfig_Log.Active := false ;
adoMetaQuery.Active := false ;
adoTemp.Active := false ;
adoTargetQuery.Active := false ;

//cdsTargetField.Free ;
//adoConfig_Log.Free ;
//adoMetaQuery.Free ;
//adoTemp.Free ;
//adoTargetQuery.Free ;

//cdsTargetField := nil ;
//adoConfig_Log := nil ;
//adoMetaQuery := nil ;
//adoTemp := nil ;
//adoTargetQuery := nil ;
//cdsTargetField.Destroy ;
//adoConfig_Log.Destroy ;
//adoMetaQuery.Destroy ;
//adoTemp.Destroy ;
//adoTargetQuery.Destroy ;
FreeAndNil(cdsTargetField) ;
FreeAndNil(adoConfig_Log) ;
FreeAndNil(adoMetaQuery) ;
FreeAndNil(adoTemp) ;
FreeAndNil(adoTargetQuery) ;
adoMetaConnection.Connected := false ;
adoConfigConnection.Connected := false ;
adoTargetConnection.Connected := false ;
//adoMetaConnection.Free ;
//adoConfigConnection.Free ;
//adoTargetConnection.Free ;
//adoMetaConnection.Destroy ;
//adoConfigConnection.Destroy ;
//adoTargetConnection.Destroy ;
FreeAndNil(adoMetaConnection) ;
FreeAndNil(adoConfigConnection) ;
FreeAndNil(adoTargetConnection) ;
//adoMetaConnection := nil ;
//adoConfigConnection := nil ;
//adoTargetConnection:= nil ;


CoUnInitialize;//必须使用
inherited destroy;
end;

procedure transThread.TransData;
begin
//本来有代码,这里暂时删除,因为我把这里代码注释的情况下,内存还是不断上涨
end ;

end.
 
你的 线程对象创建以后释放了吗?
Destroy 是否执行?
 
线程对象如何释放阿?我已经设置了FreeOnTerminate := True;应该是自动释放吧,另外,我做了测试,确实是因为创建tadoconnnection和tadoquery的原因,并且如果我将tadoquery的打开部分注释的话,内存涨的速度也会变慢。
 
好,帮顶


--------签名档---------------------------

比肩国内顶尖源码下载站点 -> 源码我爱你

http://www.source520.com
http://www.source520.net
80G源码电子书免费免注册下载,大量精辟技术文档库随时更新
******************************************************************
附:为了站点持续发展,现有本站近年来收藏的大量大型商业源码低价出售,
详情请进入以下链接查看:
http://www.source520.com/building_delphi.htm

浏览商业代码请从如下URL进入查看实物:
1.商业源码库1: ftp://source520see3:browse@61.152.199.245/
2.商业源码库2: ftp://source520see2:browse@61.152.199.245/
 
FreeOnTerminate 并不是自动释放
设置FreeOnTerminate := True是为了当线程结束时候触发OnTerminate事件
在OnTerminate事件里你可以释放你创建的对象
 
freeandnil试一下
 
freeonterminate为true的话,是线程自己释放,不用去管理的,放心吧。但是给你一个建议,你可以将你的ado方面的东西放在线程的execute中来创建和释放,而create的时候,只是负责传入一些属性字符串,而这些属性字符串刚好是execute中创建的ado控件用的,这个绝对是一个好办法。当然,ado控件就成了execute中的局部变量了,在execute的var部分声明就可以了。然后在execute中的
while not terminateddo

begin
//////
end;
后面就是释放这些对象的。你做做看。
 
后退
顶部