如何找出我的记忆去向

Posted

技术标签:

【中文标题】如何找出我的记忆去向【英文标题】:How to find out where my memory is going 【发布时间】:2010-06-01 08:41:21 【问题描述】:

我遇到了这样一种情况,即加载然后关闭文档的循环会占用几 Mb 的 RAM。此内存不会泄漏,因为 something 拥有它并在应用程序退出时清理它(Visual Leak Detector 和 Mac Leaks 工具对此表示同意)。但是,我想知道它的去向。我假设它是应用程序中的某种缓存,当文档加载时会被填充,但在文档关闭时不会被释放。我可以使用哪些方法或工具来找出这些分配是在哪里进行的?

更新:

按照 Hans 的帖子,我在应用程序中添加了一个循环来重复打开和关闭文档。我发现在加载前几个文档后,内存使用量(Process Explorer 报告的“私有字节”)出现了初始跳跃,但之后不再每次都增加。所以这表明没有新的分配,而明显的增加很可能主要是由于分页造成的。

我还仔细研究了 mac 上的 Instruments,这对于查看分配发生的位置很有用:创建一个由 Allocations 和 Leaks 工具组成的 Instrument,然后在循环的开始和结束时添加一个堆快照并且在 Heapshots 列表中,它将显示相对于最后一个快照的所有分配增量。这表明在 Mac 上,内存分配正在增加,但这是由于 CoreGraphics 绘图等内部缓存,我们几乎无法控制。

【问题讨论】:

如果您打开/关闭打开/关闭打开/关闭,每次打开/关闭时它会多消耗几 Mb,还是在第一次尝试后达到固定大小。另外,您如何测量使用的内存? 【参考方案1】:

如果您可以可靠地重现此问题,您应该能够使用 MS CRT 中的调试堆来解决此问题。从这里开始:Memory Leak Detection and Isolation

【讨论】:

我可以尝试一下——我已经有几年没有尝试过使用 MS CRT 例程了,因为过去它们不是使用我们的代码库构建的。我认为它不喜欢使用“新位置”。【参考方案2】:

假设它实际上是您测量的 RAM:确保这完全正常。您的程序在加载文档时正在主动寻址虚拟内存页面,它们将被映射到 RAM。它们会一直留在那里,直到另一个进程需要将页面映射到 RAM。某些操作系统会先发制人地修剪工作集,例如在 Windows 上,当应用程序的窗口最小化时。

如果它实际上是您测量的虚拟内存页面:那也很正常。释放内存后,堆块将添加到空闲块列表中,以供下一次内存分配使用。如果释放内存恰好释放了整个页面范围,则内存管理器有机会取消映射该范围。它不会经常发生,它是您的内存管理器的实现细节,它这样做的积极程度。

【讨论】:

有用的 cmets -- 我没有考虑过。也许我需要运行一个测试用例,应用程序将反复打开和关闭文件,以查看它是否真的分配了更多内存,或者它是否只是分页的一个怪癖。我测量的值是 Process Explorer 报告的“Private Bytes”。 那是虚拟内存,不是 RAM。它包括堆中的空闲块。【参考方案3】:

嗯,实际上你有泄漏。 当应用程序退出时,操作系统会清理所有资源:在退出后永久分配内存的意义上,没有应用程序泄漏。 XCode 有一个工具可以帮助您识别泄漏。 往下看

Run->Run with performance Tool->Leaks
这将运行您的应用程序,并使用可帮助您查找泄漏的代码进行检测。

【讨论】:

我忘了:它也会给你一个可视化的工具,用来观察什么被泄露了,以及导致泄露的调用栈。 我提到我已经运行了 Leaks 并没有发现问题。内存很可能由应用程序内部的缓存分配,并且该缓存在应用程序退出时被正确释放。我的问题是如何找到占用所有内存的特定缓存,以便在关闭文档时刷新它? 我的错:我没有意识到您的意思是 Xcode Leaks 性能工具。是视觉泄漏检测器还是 Mac 泄漏?【参考方案4】:

可能对某人有帮助。我认为激活僵尸对象检测的 Xcode 4.2(方案编辑中的复选框)会像疯了一样吃掉内存 - 大约 4GB 在一分钟内。只要确保检查这一点,以防您的应用程序占用在 Xcode 下运行的内存,否则不会。内存分配和泄漏工具也没有提供任何东西。

【讨论】:

以上是关于如何找出我的记忆去向的主要内容,如果未能解决你的问题,请参考以下文章

找出是啥让我在 torch7 中记忆犹新

如何测试记忆函数?

为啥使用数组比使用地图记忆更快?

登录laravel 5后如何获取会话记忆?

如何在 Lisp 中记忆递归函数?

提升记忆力的方法(未编辑整理的)