我应该使用哪些 Instruments 工具来了解我的 Monotouch 应用程序的内存使用情况?

Posted

技术标签:

【中文标题】我应该使用哪些 Instruments 工具来了解我的 Monotouch 应用程序的内存使用情况?【英文标题】:What Instruments tools should I use to find out about my Monotouch app's memory usage? 【发布时间】:2012-05-01 19:07:51 【问题描述】:

我已经阅读了很多关于在 Instrument's 中跟踪内存使用情况的文章,但发现很少与 Monotouch 结合使用。

这里似乎有三个反对的主张:

    使用InstrumentsAllocation实用程序。 “活动字节”的数量是应用程序使用的物理内存量。 使用内存监视器插件。从进程列表中,选择您的应用并检查“真实内存”列。这是当前使用的 RAM 量。 使用 VM Tracker 并制作自动快照。 “脏大小”,如果你想要的话。

据我观察:

一旦触发 GC,“Real Memory”就会下降 即使我的“Live Bytes”保持在 30MB 左右,我最终也会收到内存警告 在“实时字节”不变的情况下,“实际内存”可以显着增加,并且可以轻松增长到 200MB 或更多。 在使用 QLPreviewController 并查看一个非常大的 Word 文档(1000 页)时,滚动浏览该文档会疯狂地增加实际内存。如果收到内存警告,则实际内存和活动字节都不会下降。最终,应用程序会崩溃; Monotouch 问题还是 Apple 的问题? 有时,真实内存似乎在增长,没有什么可以阻止它。再说一次,GC 似乎清除了大部分。这没有真正的模式。

那么正确答案是什么?真的有吗?

编辑:我附上了两张图片。一个显示在我的应用程序生命周期中的一个阶段的内存使用情况,以及稍后的几秒钟。两个图像都反映了 UI 中同一点的内存使用情况,屏幕上只有两个控制器。也许有人仍然可以评论从这些数字中可以读出什么,尤其是神奇的“记忆标签 70”。

【问题讨论】:

【参考方案1】:

仪器有点像一个黑匣子,但我认为它是这样的:

这里似乎有三个相反的说法: 1. 使用 Instruments 的 *Allocation*s 实用程序。 “活动字节”的数量是应用程序使用的物理内存量。

我不确切知道“Live Bytes”是什么,但这不是应用程序使用的物理内存量。我认为这是所有ObjectiveC对象使用的物理内存量(如果这个理论是正确的,“Live Bytes”不包含托管代码使用的任何内存,也不包含ObjectiveC对象间接使用的任何内存(例如图像数据),这似乎是真的)。如果您想跟踪泄漏的对象,“Live Bytes”绝对有用,但它不是(必然)一个很好的指标,可以指示实际使用了多少内存。

2 。使用内存监视器插件。从进程列表中,选择您的应用并检查“真实内存”列。这是当前使用的 RAM 量。

这有点接近:“Real Mem”是应用程序正在使用的不与其他应用程序共享的物理内存量。应用程序使用的物理内存总量是“虚拟内存”,但应用程序之间共享了大块“虚拟内存”(即,共享库在加载到内存时当然会使用内存,但由于它是不可变的,它会只为所有进程加载一次。但是它将被添加到每个进程的“虚拟内存”中,所以如果你添加所有进程使用的“虚拟内存”,你将远远超出设备的实际物理内存)。

3 .使用 VM Tracker 并制作自动快照。如果你追求的是“脏大小”。

正确。 “Dirty Size”是您所追求的 - 然而,这与“Real Mem”密切相关,它只是将“Real Mem”分为几类,以便您可以轻松查看正在使用内存的内容。

对于典型的图片泄露占用大量内存的情况,流程如下: 1. 使用内存监视器验证您的应用确实存在内存问题。 2. 在 VM Tracker / "Dirty Size" 中看到图像数据使用了大量内存(这就是神奇的 "Memory Tag 70")。 3. 使用 Allocations 找出 CGImage 的创建位置,查看相应的堆栈跟踪并追踪这些图像未释放的原因。

虽然每个应用程序都不同,所以不可能想出一个适用于所有情况的简短配方。

一旦触发 GC,“Real Memory”就会下降 即使我的“Live Bytes”保持在 30MB 左右,我最终也会收到内存警告 在“实时字节”不变的情况下,“真实内存”可以显着增加,并且可以轻松增长到 200MB 或更多。

所有这些都在上面解释过。

在使用 QLPreviewController 并查看一个非常大的 Word 文档(1000 页)时,滚动浏览该文档会疯狂地增加实际内存。如果收到内存警告,则实际内存和活动字节都不会下降。最终,应用程序会崩溃; Monotouch 问题还是 Apple 的问题?

这也可能是你的问题 :) 如果不知道内存的去向,就无法判断。

有时,真实内存似乎在增长,没有什么可以阻止它。再说一次,GC 似乎清除了大部分。这没有真正的模式。

您的意思是当您的应用程序完全没有执行任何操作时,您正在观察真实内存的增长?如果你真的在你的应用中做某事,这是完全正常的。

【讨论】:

关于您的 cmets 到 QLPreviewController 和实际内存增长:对于 QLPreviewController 的内存使用情况,我不知道该怎么做。只需创建一个测试应用程序并给它一个巨大的文档并滚动,您就会看到真正的内存增长。关于内存增长:我的意思是,有时应用程序会被 60MB 的实际内存杀死,有时会被 200MB 的实际内存杀死。而且我的感觉是 GC 有时无法归还未使用的内存,但我无法证明它(但 :-))。 我验证了,我可以看到我 50% 的脏内存来自“内存标签 70”——这是什么? @Krumelur:更新答案以包含有关内存标签 70 的信息(它是图像数据)

以上是关于我应该使用哪些 Instruments 工具来了解我的 Monotouch 应用程序的内存使用情况?的主要内容,如果未能解决你的问题,请参考以下文章

了解 Alloc 的 Instruments 结果中的负责任调用者

了解 Xcode 中的 Instruments,测试泄漏

如何在 Instruments 上跟踪 UI 事件

转使用Xcode和Instruments调试解决iOS内存泄露

Instruments使用技巧

iOS Instruments工具使用