繁体   English   中英

使用Delphi的内存泄漏

[英]Memory leak using Delphi

我有这个程序:

procedure TMainForm.ExtractActor(const actor_id : string);
var
  mystream : TStringStream;
  js : TlkJSONobject;
begin
    mystream:= TStringStream.Create('');
    idHTTP1.Get(TIdURI.URLEncode('some dynamic url'),mystream);                                               
    js := TlkJSON.ParseText( mystream.DataString ) as TlkJsonObject;
    //insert
    if UniConnection1.Connected then
    begin
      UniQuery3.Params[0].Value:= StrToInt(js.getString('id'));
      UniQuery3.Open;
      if (UniQuery3.RecordCount = 0) then
      begin
        Uniquery2.Params[0].Value:= StrToInt(js.getString('id'));
        Uniquery2.Params[1].Text:= js.getString('name');
        Uniquery2.Params[2].Text:= js.getString('locale');
        Uniquery2.Params[3].Text:= js.getString('gender');
        Uniquery2.Params[4].Text:= js.getString('username');
        Uniquery2.Execute;
      end;
      UniQuery3.Close;
    end;
    mystream.Free;
end;

监视Windows任务管理器我看到进程内存在不断增加。 大约一天后,我将收到内存不足错误,并且应用程序将崩溃。 我究竟做错了什么? 我假设JSON或Devart UniDAC库都没有泄漏。

造成泄漏的原因很明显。

肯定是泄漏的是您创建但未能销毁的js对象。 通过try / finally块保护其生命:

js := TlkJSON.ParseText( mystream.DataString ) as TlkJsonObject;
try
  ...
finally
  js.Free;
end;

mystream保护的mystream更微妙。 如果在分配mystream之后mystream之前引发了异常,则将泄漏该对象。 同样,您应该使用与上面演示的完全相同的惯用语try / finally块来保护它。 mystream的问题仅在您的函数引发异常的情况下才是您的问题。 尽管在这种情况下可能并非如此,但您必须始终以上述方式保护对象。

无论如何,您当然应该在程序中进行一些泄漏跟踪。 可能会有更多的泄漏。 这是您需要采取的第一步:

  1. 更改您的代码,使其使用完整版本的FastMM。
  2. 设置FastMM配置文件以进行完全调试。 这可能涉及编辑.inc文件,如果您发现这太令人生畏,则可以从此处使用GUI实用程序: http : //jed-software.com/blog/?p=606
  3. 运行您的程序一段时间,然后关闭它。 如果您有泄漏,应在此时报告。
  4. 修复所有泄漏。

程序运行期间可能会出现泄漏,但是在程序关闭时,所有泄漏都会被清除。 这些很难跟踪,并且需要对程序进行一些额外的检测。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM