在上一篇文章(My program never releases the memory back. Why?)中,我展示了FastMM可以缓存(读取为自身保持)相当大的内存。如果您的应用程序刚刚在RAM中加载了大量数据集,则在释放数据后,您将看到令人印象深刻的RAM未释放回内存池。
我环顾四周,似乎调用SetProcessWorkingSetSize API函数会将缓存“刷新”到磁盘。但是,我无法决定何时调用此函数。我想在执行RAM密集型操作的按钮上的OnClick事件结束时调用它。但是,有些人说这可能会导致AV。
如果有人成功使用此功能,请告诉我(我们)。
非常感谢。
编辑:
1.释放数据集后,程序仍然占用大量RAM。调用SetProcessWorkingSetSize后,大小返回到几MB。有人争辩说什么都没有被释放。我同意。但是内存占用现在很小,并且在正常使用程序后不会增加(例如,在执行不涉及加载大型数据集的正常操作时)。不幸的是,没有办法证明交换到磁盘的内存被装回内存,但我认为不是。
我已经证明了(我希望)这不是内存泄漏:
My program never releases the memory back. Why?
How to convince the memory manager to release unused memory
答案 0 :(得分:13)
如果SetProcessWorkingSetSize可以解决您的问题,那么您的问题不是FastMM保持内存。由于此函数只是通过将RAM中的内存写入页面文件来修剪应用程序的工作集。什么都没有发布回Windows。
实际上你只是慢慢地再次访问内存,因为它现在必须从光盘中读取。此方法与最小化应用程序具有相同的效果。然后Windows假定您不会很快再次使用该应用程序,并将工作集写入RAM页面文件。 Windows可以很好地决定何时将RAM写入页面文件,并尝试尽可能长时间地将最常用的内存保留在RAM中。当剩余的RAM很少时,它将使工作集大小更小(写入页面文件)。我不会惹它只是为了给你一个错觉,你编程使用更少的内存,而事实上它正在使用与以前一样多,只是现在它访问速度较慢。再次访问的内存将再次加载到RAM中,并使工作集大小再次增长。触及更少的内存可以缩小工作集的大小。
所以不,这不会帮助你强迫FastMM释放内存。如果你的目标是让你的应用程序使用更少的内存,你应该寻找其他地方。寻找泄漏,寻找堆碎片寻找优化,如果你认为FastMM阻止你这样做,你应该尝试找到支持它的事实。如果你的目标是保持你的工作集大小,你可以尝试保持你的内存访问本地。也许FastMM或其他内存管理器可以帮助你,但与使用大量内存相比,这是一个非常不同的问题。也许这个函数可以帮助你解决你遇到的问题,但我会谨慎使用它,当然不会只是为了保持你的程序内存使用率低的错觉。
答案 1 :(得分:4)
我同意 Lars Truijens 100%,如果你没有,你可以在调用API SetProcessWorkingSetSize之前和之后通过FasttMM调用GetMemoryManagerState和GetMemoryManagerUsageSummary检查FasttMM内存使用情况。
答案 2 :(得分:3)
你确定有问题吗?工作集可能只会在确实存在内存不足时减少。
答案 3 :(得分:2)
问题解决了:
我不需要使用SetProcessWorkingSetSize。 FastMM最终将释放RAM。
要确认此行为是由FastMM生成的(正如Barry Kelly建议的那样),我创建了第二个分配了大量RAM的程序。一旦Windows用完RAM,我的程序内存利用率就恢复到原来的值。
答案 4 :(得分:0)
当我实现TWebBrowser时,我只使用过一次这个函数。即使我销毁了实例,这个组件也占用了我很多内存。