procedure getipl;
var
 ado:TADOQuery;  
begin
 ado:=TADOQuery.Create(nil);
ado.Connection :=Form1.ADOConnection1;
Form1.ADOConnection1.Connected :=True;.......
ado.free;
//freeandnil(ado); 这个也不行
end;
用try... finally最后释放也不真正释放,执行多次这个过程程序占用内存就一直增加真是郁闷,怎么回事呢?

解决方案 »

  1.   

    堆分配内存:   adoquery 创建分配内存 释放后 内存成为“碎块” 被系统回收,但是仍占用内存,   第二次需要分配内存时 如果需求内存大于碎块大小则重新分配,如果小于的话 直接调用碎块内存因此adoquery在重复申请过程中应该只占用第一次大小内存 
      

  2.   


    谢谢你,我用了个线程执行这个过程99次,内存真的像你说的那样,增加到一定程度就不再增加了
    不过这个过程在其他过程里调用,然后执行调用它的过程199次,发现内存一直在增加,郁闷啊我的代码是这样,一个全局的stringlist保存数据库里的记录序号,然后随机打乱序号后,读入打乱后的序号,然后把每个序号对应的数据库记录重新读入到一个临时的数据库表里,最后又从临时数据库表读入数据重新写到数据库,这样就完成随机排序function  ranip(list:string):string ;
    var
     tls1,tls2:TStringList;
     i,i2:Integer;
     ado,ado2:TADOQuery;begin
     tls1:=TStringList.Create;
     try
     tls2:=TStringList.Create;
     try
     tls1.Text :=ipidlist.Text;
     for i:=0 to tls1.Count-1 do
     begin Randomize;
     i2:=Random(tls1.Count);
     if i2= tls1.Count then i2:= tls1.Count-1;
     tls2.Add(tls1.Strings[i2 ]  );
     tls1.Delete(i2);
     end;
     //Form1.Memo6.Text :=sidlistid.Text+'|'+tls2.Text; ado:=TADOQuery.Create(nil);
     try
     ado.Connection :=Form1.ADOConnection1;
     Form1.ADOConnection1.Connected :=True;
      ado2:=TADOQuery.Create(nil);
     try
     ado2.Connection :=Form1.ADOConnection1;
     Form1.ADOConnection1.Connected :=True;
      ado.SQL.Text :='delete from tmpiplist';
    ado.ExecSQL;for i:=0 to tls2.Count -1 do
    begin
    ado2.SQL.Text :='select * from '+'iplist'+' where id='+tls2.Strings[i] ;
    try
    ado2.Active:=True;
     except
      try
       ado2.Active:=True;
       except
       end; end;if ado2.RecordCount <>0 then
    begin
    ado.SQL.Text :='insert into '+'tmpiplist'+' (ip,ipport,speed,atime,who,https)values('''+ado2.FieldValues['ip']+''','''+ado2.FieldValues['ipport']+''','''+ado2.FieldValues['speed']+''','''+ado2.FieldValues['atime']+''','''+ado2.FieldValues['who']+''','''+ado2.FieldValues['https']+''')';
    ado.ExecSQL;
    end;
    end;  ado.SQL.Text :='delete from iplist';
    ado.ExecSQL;ado2.SQL.Text :='select * from '+'tmpiplist'+' where id';
    try
    ado2.Active:=True;
     except
      try
       ado2.Active:=True;
       except
       end; end;for i:=1 to ado2.RecordCount do
    beginado.SQL.Text :='insert into '+'iplist'+' (ip,ipport,speed,atime,who,https)values('''+ado2.FieldValues['ip']+''','''+ado2.FieldValues['ipport']+''','''+ado2.FieldValues['speed']+''','''+ado2.FieldValues['atime']+''','''+ado2.FieldValues['who']+''','''+ado2.FieldValues['https']+''')';
    ado.ExecSQL;
    ado2.FindNext;
    end;
     // MessageBox (0,'','',MB_OK );
     getipl;
      finally
        ado2:=nil;
     ado2.free;
     end;
     finally
          ado:=nil;
     ado.Free;
     end;
     finally
      tls2:=nil;
     tls2.free;
     end;
    finally
     tls1:=nil;
     tls1.Free;
     end;end;
      

  3.   

     ado2:=nil;
     ado2.free;
     end;
     finally
          ado:=nil;
     ado.Free;
     end;
     finally
      tls2:=nil;
     tls2.free;
     end;
    finally
     tls1:=nil;
     tls1.Free;
     end;
    ----------------
    说说你吧  看了你这能把人弄疯了ado1:=nil;//你都把ado1指针指空了那你下面释放ado1指向的内存就是空 而原先的ado1指针指向的内存并没有释放
    ado1.free;//释放啥 没用freeandnil(ado1);
    或者ado1.free;
    ado1:=NIL;
      

  4.   

    强行回收内存。    EndHandle: HWND;     //释放内存处理句柄
        currentMinWorkingSetValue, currentMaxWorkingSetValue: DWORD; //当前进程工作区大小EndHandle := GetCurrentProcess();
        if GetProcessWorkingSetSize(EndHandle, currentMinWorkingSetValue, currentMaxWorkingSetValue) then
        begin
            SetProcessWorkingSetSize(EndHandle, currentMinWorkingSetValue, currentMaxWorkingSetValue);
        end;
      

  5.   


    呵呵,我开始是直接ado.free的,也试了freeandnil(ado);最后看到其他朋友说先nil,然后再free.所以就是这个代码,不过按你说的不nil直接free,内存虽然不断增加,但是都是增加的很小
      

  6.   

    内存泄露了 Test = class
      public
        destructor Destroy; override;
      end;
      
      destructor Test.Destroy;
      begin
        ShowMessage('Destroy');
        inherited;
      end;  调用
      var
        T1: Test;
      begin
        T1 := Test.Create;
        T1 := nil;
        T1.Free;很明显, 析构函数不会被调用VCL  TOBJCET Free的源代码procedure TObject.Free;
    begin
      if Self <> nil then
        Destroy;
    end;在不等于nil的情况下才会调用 Destroy
      

  7.   

    一个FreeAndNil(对象)就够了 
      

  8.   

    ado.free;
    ado:=nil;这个说得对,试后给出答案行不行吧
      

  9.   


    还是一样,内存一直增加,但是增加量不大
    编译提醒ado:=nil;   never used我的代码是这样,一个全局的stringlist保存数据库里的记录序号,然后随机打乱序号后,读入打乱后的序号,然后把每个序号对应的数据库记录重新读入到一个临时的数据库表里,最后又从临时数据库表读入数据重新写到数据库,这样就完成随机排序
      

  10.   

    MDB数据库随着打乱次数慢慢增加,不知道有没有其中的联系打乱数据记录的过程是这样,先读数据库记录序号,打乱数据库记录序号,按打乱后的序号一个个读数据库记录到一个临时的表里,读前先清除临时表的记录,再删除原来的表记录,再从临时表读数据回到原来的表
      

  11.   

    没有用过这个VCL我操作数据库都是用原生代码,查下你这个VCL是不是对象生命期自控制呢?如果是的话如果是每次实例化一个对象,内部会加1,卸载减1,等0才会真正释放