你能帮我解决一下这个问题。这是我的代码。我存储(在此示例中)10000个字符串,当我尝试删除它们时,只有一些内存被释放,其余的泄漏。
type
PMyData = ^TMyData;
TMyData = record
Name: string;
end;
////////
var
XList:Tlist;
//////////
// Here is how I add//
var
MyData: PMyData;
I:Integer;
begin
for I:=0 to 10000 do begin
New(MyData);
MyData.Name:='Hello';
XList.Add(TObject(MyData));
end;
end;
///Here is how I delete///
var
MyData: PMyData;
I:Integer;
begin
for I:= XList.Count - 1 downto 0 do begin
MyData:=PMyData (XList[I]); /// I also used (XList.Items[I]) but the result is the same
Dispose(MyData);
XList.Delete(I);
end;
答案 0 :(得分:6)
我发现该代码没有泄漏。你是如何确定发生泄漏的?你在看任务管理器吗?如果是这样,那么这不是检测内存泄漏的可靠方法。 VCL内存管理器不会将释放的内存释放回操作系统,它会被缓存以供以后重用。任务管理器显示分配的内存它没有关于应用程序实际管理内存的概念。
答案 1 :(得分:5)
据我所知,只要您有效地执行清理代码,此代码就不会泄漏 判断代码是否泄漏的唯一方法是要求内存管理器通过在代码中的某处添加此指令来报告任何泄漏(确保它已执行):
ReportMemoryLeaksOnShutdown := True;
当应用程序终止时,内存管理器将告知代码请求的任何内存是否未被释放,即您的代码是否有泄漏。
在那之后,内存管理器的工作是在终止时将内存返回给操作系统,并且它正确执行。
现在,为什么当字符串数量增加时,为什么TaskManager报告显然没有释放更多的内存,这是因为一旦字符串被释放,内存管理器不会将所有先前请求的内存放弃到操作系统,以防以后需要再次使用;为了避免再次从操作系统请求,它保留它。
正如其他答案中所述,TaskManager不是发现内存泄漏的好工具......
答案 2 :(得分:4)
Windows任务管理器不是衡量内存使用情况的可靠方法。使用FastMM4内存管理器打开泄漏跟踪。
答案 3 :(得分:3)
您的代码看起来不错。究竟是什么意思,只有一些记忆被释放而其余记忆泄漏了?您是从FastMM获取内存泄漏报告,还是只是没有看到任务管理器中的内存使用计数器一直退回?
如果您没有看到您的程序将所有内存都恢复,那就是设计。它保留了一些,所以如果你分配更多的内存,它不需要立即从Windows请求更多,这有助于提高性能。如果内存管理器实际上没有回收内存,那么内存只会被“泄露”。
答案 4 :(得分:0)
在Dispose之前调用以下函数或将记录更改为class(TObject)
的Finalize(迈德特^);
干杯
答案 5 :(得分:0)
记录指针包含的任何时候 变种 未绑定的数组,如......数组...... 字符串除了短字符串类型 接口 在进行FreeMem或Dispose之前,你需要调用Finalize来释放这些数据。否则使用class更好
干杯
答案 6 :(得分:0)
尝试:
FreeAndNil(XList.Items[I]);
XList.Delete(I);