0
我有一個程序接受SQL查詢作爲命令行參數,查詢PostgreSQL數據庫並生成一個文件格式爲多種方式之一(通常用於生成CSV文件)。字符串中的Delphi內存泄漏?
但是,該程序有嚴重的內存泄漏 - 一個特定的查詢生成12MB文件,該程序使用8GB的RAM加上幾GB的交換空間,然後操作系統將其殺死。我想找到這個內存泄漏的原因。我不太瞭解德爾菲(根據程序的質量來判斷,原作者也沒有),但我的任務是找到一個快速解決方案。
以下doData
函數部分輸出一行結果集。我猜測問題出在「複製」命令的問題上(在堆上創建一個永遠不會釋放的字符串),但我確定有人比我更有經驗能夠確認這個答案,或者指向我正確的方向。
procedure doData;
var
s, fldVal : string;
i, fldLen : integer;
begin
s := '';
for i := 0 to ds.Fields.Count-1 do
begin
if (ds.Fields[i].DataType = ftDate) or
(ds.Fields[i].DataType = ftDateTime) then
begin
if psql.outDate = 'i' then
fldLen := 8
else
fldLen := 10;
if ds.Fields[i].IsNull then
fldVal := ''
else
fldVal := formatDate(ds.Fields[i].AsDateTime);
end
else
begin
fldLen := ds.Fields[i].DisplayWidth;
fldVal := ds.Fields[i].AsString;
end;
if (psql.outType = 'd') or (psql.outType = 's') then
s := s + trim(fldVal)
else if psql.outType = 'f' then
begin
s := s + fldVal;
if fldLen - length(fldVal) > 0 then
s := s + copy(spaces, 1, fldLen - length(fldVal));
// Is this a memory leak above?
end;
if psql.outType = 's' then
begin
if i < ds.Fields.Count-1 then
s := s + psql.outDelimChar;
end
else
s := s + psql.outDelimChar;
end;
writeln(psql.outPrefixData + s);
end;
德爾福字符串類型與參考計數管理。當一個字符串變量超出範圍時,它會自動銷燬。 'Copy'不能在這段代碼中產生內存泄漏。 –
如果你生產的是12MB的字符串,那麼你做錯了事情:改用TStringBuilder(或直接寫入流)。但使用's:= s + xx'這樣的代碼對於內存處理來說是非常糟糕的 – Daniel
我發現'MadExcept'是識別內存泄漏的有效工具,但是從你的代碼片段開始,我可能會檢查'ds'和'psql'得到釋放 - 你可能會很幸運...... –