我有一个程序接受SQL查询作为命令行参数,查询PostgreSQL数据库并生成一个以多种方式之一格式化的文件(通常用于生成CSV文件)。
然而,这个程序有严重的内存泄漏 - 一个特定的查询产生12MB文件,该程序使用8GB的RAM加上几GB的交换空间,然后操作系统将其杀死。我想找到这个内存泄漏的原因。我不太了解德尔福(从程序的质量来看,原作者也没有),但我的任务是找到快速解决方案。
以下doData
函数部分输出结果集的单行。我猜测问题出在" copy"命令(在堆上创建一个永远不会被释放的字符串),但我确信比我更有经验的人能够确认这个答案或指出我正确的方向。
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;
答案 0 :(得分:4)
此代码中没有泄漏。 Delphi string
类型由编译器管理,不需要程序员显式释放内存。
如果您希望找到泄漏,则应包括FastMM的完整调试版本。这将生成代码中任何泄漏的诊断报告,包括有助于识别泄漏内存最初分配位置的堆栈跟踪。