Delphi:TAdoQuery内存泄漏?

我正在使用Delphi 5和ADO开发小型糖尿病计划。我这样做一个小问题:
function GetLowestGlucoseLevel(StartDate:string;EndDate:string): Integer;
var
  Q:TADOQuery;
begin
   try
      Q:=TADOQuery.Create(Application); //Separate unit, owner set to App
      Q.Connection:=dtMod.ADOCon;
      Q.DisableControls;
      Q.Close;
      Q.SQL.Clear;
      Q.SQL.Add('SELECT Min(qGlucose.Glucose) AS MinOfGlucose from qGlucose');
      Q.Parameters[0].Value:=StartDate;
      Q.Parameters[1].Value:=EndDate;
      Q.Open;

      Result:=Q.FieldByName('MinOfGlucose').AsInteger;

      Q.Close;
    finally
      Q:=nil;
      Q.Free; 
    end; 
end;
查询运行正常并按预期返回结果。但是,当我检查Windows任务管理器时,内存使用率在查询后继续上升而不是减少。 如何解决这个问题? 谢谢!     
已邀请:
你首先将它设置为nil,然后在nil变量上调用
Free
(它什么也不做),从而泄漏
TADOQuery
    
你安装了Delphi 5更新了吗?该 已知RTM ADO实现 有问题。 使用FastMM4,它应该使用 Delphi 5也是如此,并告诉你更多 关于泄漏的位置。     
德尔福方式:
function GetLowestGlucoseLevel(const StartDate:string; const EndDate:string): Integer;
var
  Q:TADOQuery;

begin

    Q:=TADOQuery.Create(nil); //(nil) because local use only. Placed before tryfinally block 
                              //because if it fails to .create then there would be no object to
                              //.Free 
    try

      Q.Connection := dtMod.ADOCon;

      //------can erase these------
      //Q.DisableControls; //No controls attached so unnecessary
      //Q.Close;           //Q is local and was never opened so no need to close
      //Q.SQL.Clear;       //Q is local and was never filled so no need to clear

      Q.SQL.Add('SELECT Min(qGlucose.Glucose) AS MinOfGlucose from qGlucose');
      Q.Parameters[0].Value:=StartDate;
      Q.Parameters[1].Value:=EndDate;
      Q.Open;

      Result := Q.FieldByName('MinOfGlucose').AsInteger;

      Q.Close;

    finally 

      Q.Free;

      //Q := nil          //not needed because Q's scope is local

    end; 
end;
    
引用:
finally
  Q:=nil;
  Q.Free; 
end; 
你在开玩笑,对吧?首先是变量,然后释放它?你是个天才! :-) 使用:
finally
  Q.Free; 
  Q:=nil;
end; 
或者甚至不打算给它分配nil,因为Q是一个局部变量...... 但是重新阅读您的代码,我注意到您使用Application作为所有者。因此,它实际上不会是泄漏,因为在释放应用程序时它将被释放。如果您使用表单,则在释放所有者表单时将释放该表单。您应该尝试的是调用此查询大约100.000次以检查它是否保留内存,或者它是否只是增加内存直到达到某个大小。后者更有可能,因为内存是为将来的ADO调用保留的。     
正如其他人所指出的那样,最后一节应该颠倒两个陈述,如下:
finally
  Q.Free; 
  Q:=nil;  // <- not even necessary since this is a local var
end; 
或者您可以调用SysUtils.FreeAndNil(Q)(如果在Delphi 5中可用,则不确定)。 除此之外,TaskManager无论如何都是确定内存使用的可怕工具。您可能会为Q释放内存,但这并不意味着Delphi内存管理器会将内存释放到操作系统。     
除了像Arjan,jasonpenny和WorkShop Alex所说的那样,你可以使用Process Explorer来查看进程的实际内存消耗(Private Bytes)。任务管理器并不适合这项任务,因为它只显示流程的工作集。     

要回复问题请先登录注册