我在Win32项目中使用Delphi 5(安装了FastMM),并且最近一直在尝试大幅减少此应用程序中的内存使用量.到目前为止,我已将使用量减少了近一半,但在处理单独的任务时发现了一些问题.当我最小化应用程序时,内存使用量从45兆位缩减到1兆位,这归功于它分页到磁盘.当我恢复并重新开始工作时,内存仅增加到15兆.当我继续工作时,内存使用量再次缓慢上升,最小化和恢复将其恢复到15兆.所以我的想法是,当我的代码告诉系统释放内存时,根据Windows仍然保留它,实际的垃圾收集直到很久以后才开始.
任何人都可以确认/否认这种行为吗?是否有可能以编程方式清理内存?如果我继续使用该程序而不执行此手动刷新,我会在一段时间后出现内存不足错误,并希望消除它.谢谢.
编辑:我在about.com上发现了一篇文章,其中提供了很多内容以及其他内存管理领域的链接和数据.
在最近的帖子中(我的程序永远不会释放内存.为什么?)我表明在使用FastMM时,应用程序不会释放大量内存回系统.最近我创建了一个人工测试程序,以确保它不是一个内存的问题,它只出现在FastMM中.
在这个程序中,我创建并销毁一个对象(与前一篇文章中使用的对象相同)500次.
内存要求是("私人工作集"):
没有FastMM
在运行循环之前:1.2MB
运行循环后:2.1MB
使用FastMM(激进的调试模式)
在运行循环之前:2.1MB
运行循环后:25MB
使用FastMM(发布模式)
运行循环之前:1.8MB
运行循环后:3MB
如果我多次运行循环,则内存要求不会增加.这意味着重用未释放的内存,因此这不是内存泄漏(内存泄漏会增加内存占用,每次运行时会有几KB/MB).
我的问题是:
如何在FastMM中禁用此行为?它甚至可能吗?我知道,如果我在没有FastMM或FastMM Release Mode的情况下发布程序,它将"浪费"适量的RAM.但是,根据需要禁用此行为,将帮助我(我们?)识别内存泄漏.实际上在我的第一篇文章中(见链接),很多人都认为我有泄漏.由于这种行为,显然造成了混乱.不,很明显没有泄漏.只是内存管理器拒绝释放大量内存.
它会释放额外的内存吗?什么时候?什么引发了这个?程序员可以触发吗?例如,当我知道我已经完成了RAM密集型任务并且用户可能暂时不使用该程序(最小化它)时,我可以将RAM刷回系统吗?当用户打开我的程序的多个实例时会发生什么?他们不会争夺内存吗?
我有一个MDI计划.当它启动时需要2-3MB的RAM.然后,在这个程序中,我创建了大约260个MDI子窗口(每个窗口都有一个TStringGrid,一个位图和一些其他控件)并显示一些数据.该应用程序需要大约500MB来加载所有这些窗口.如果我手动关闭每个MDI子项,应用程序仍然使用160MB的RAM.为什么它不会返回几MB的RAM?我应该担心吗?对于只有1GB或RAM的系统来说,这是160MB!
注意:我使用任务管理器中的WORKING SET列来查看RAM统计信息.也许我需要一个更好的工具来读取RAM利用率.(私人工作集只比工作集小一点).
这不是泄漏!
FastMM(设置为激进)表示关闭程序时没有内存泄漏.有关其不是泄漏的其他证据,请参阅我的答案帖子.
我释放的东西
许多人告诉我,关闭一个儿童窗口只能隐藏它.我知道.我使用"Action:= caFree"来实际发布表单.每个表单都负责释放它所拥有的控件.
回答
我发现FastMM对此负有责任.请参阅我在下面发布的答案.
Delphi 7,Win 7 32位
类似帖子:
可以清理内存吗?
何时调用SetProcessWorkingSetSize?(说服内存管理器释放内存)
我的Delphi XE应用程序基于使用RemObjects创建的本地服务器DLL的单个EXE,并使用大量内存进行特定操作,直到它生成一个异常,说明内存不足.所以我试图理解为什么以及在哪里发生这种情况所以我在我的代码中放置了各种步骤来报告内存使用情况.问题是我根据获取内存使用信息的方法获得了非常不同的信息:
如果我使用这里解释的方法直接向FastMM请求客户端EXE和服务器DLL,这是我得到的:
现在如果我使用这里解释的使用GetProcessMemoryInfo 的方法,我得到更多的内存使用:
看起来第二种方法是基于我的记忆问题的权利,但FastMM方法怎么可能如此"低"?有什么可以解释这个区别?