我有这个程序:
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
分配之后且销毁异常之前引发异常,则将泄漏该对象。同样,您应该使用try
/finally
块使用与上面演示的完全相同的惯用法来保护它。问题mystream
仅在您的函数引发异常的情况下才是您的问题。尽管在这种情况下可能并非如此,但您必须始终以上述方式保护对象。
无论如何,您当然应该在程序中进行一些泄漏跟踪。可能会有更多的泄漏。这是您需要采取的第一步:
程序运行期间可能会出现泄漏,但是在程序关闭时,所有泄漏都会被清除。这些更难跟踪,并且需要对程序进行一些额外的检测。
本文收集自互联网,转载请注明来源。
如有侵权,请联系 [email protected] 删除。
我来说两句