4

我有一个在模拟器中运行良好的 iPhone 应用程序。它通过摆脱并非绝对必要的所有内容来很好地响应内存警告。当我在设备上运行它时,它运行良好。但是经过一定量的使用后,它会因错误代码 101 而崩溃——据我所知,这是操作系统因内存使用而杀死它。我可以看到内存警告(我正在记录它),我的应用程序对其做出响应,但此后不久就死了。

如果我查看 Instruments 中的应用程序(在设备上或在 sim 中),它没有发现任何泄漏。此外,净内存使用量在 600-700k 字节范围内。从我的应用程序的不同视图转换会增加内存使用量(如预期的那样),但是当视图和控制器被释放并解除分配时,内存使用量永远不会像以前那么低。但是,加法通常只是 1000-2000 字节范围内的内容。因此,虽然 Leaks 显示没有泄漏,但我怀疑某处存在问题。我还查看了我正在分配的所有对象,所有这些对象似乎都按预期被回收了。我看到的唯一不断增加的对象是 GeneralBlock-N(其中 N 是某个数字)

我应该不关注仪器净使用量吗?尝试诊断问题的下一步是什么?

补充:我没有对 malloc() 或任何会返回我负责的缓冲区的 CoreFoundation 库进行任何调用。我正在进行的唯一非 Obj-C 调用是将语句记录到 NSLog。

4

5 回答 5

7

快速尝试的一件事是运行Clang 静态分析器。这将在您的代码中找到您可能遗漏的一些(但不是全部)问题。它在编译时检查代码,所以它绝不是万无一失的,但几乎肯定会发现最明显的问题。

于 2008-11-11T18:52:21.013 回答
4

您还应该使用内存监视器工具运行您的应用程序,以查看设备上的整体系统使用情况。

于 2008-11-11T22:08:21.147 回答
2

Leaks 只查找未被任何内容引用但仍保留的内存。

您所看到的是您保留了记忆,并且仍然被某些东西引用。

需要特别注意的一件事是,如果您已将一个类的引用作为委托传递给其他东西,那么您可以在您的 dealloc 方法中释放它。

同样,如果您订阅了任何通知,您应该在 viewWillDisappear 中取消订阅:(如果您在视图控制器中使用通用取消订阅方法,请不要忘记重新订阅内存警告通知。

计时器也是如此,当视图消失时停用它们,并在视图返回时重新启用它们(当然,除非您需要在应用程序运行的整个过程中运行计时器)。

基本上对任何你提供一个类的引用的东西都持怀疑态度,并试着弄清楚你如何尽可能地消除那个链接(在 dealloc 或 viewWillDisappear: 或两者中)。

于 2008-11-12T03:37:18.097 回答
2

以下是我所学内容的摘要(感谢一些出色的答案和评论):

  • 对象分配与内存使用不同。我关于 ObjectAlloc 的净字节元素的问题的答案是,您不应该关注它 - 至少在确定您正在使用的内存量问题或导致它崩溃的原因时不应该关注它。它不能反映应用程序的真实内存使用情况。
  • 我的业余猜测是 ObjectAlloc 只显示直接对象本身占用的内存。因此,如果您有一个 UIImageView,它只占用少量字节来存储各种属性,但它可能指向内存中的图像,占用大量空间。因此,查看 ObjectAlloc 仅有助于确保您没有创建和保留对象,它不会让您了解您正在使用多少内存或在崩溃之前可以使用多少。
  • MemoryMonitor 将为您提供总内存使用情况。您可以使用 Instruments 窗口右下方的搜索工具将其限制为仅查看您的应用程序的使用情况。
  • ObjectAlloc 和 Memory Monitor(以及 Leaks 工具)都是 Instruments 的插件 - 以防其他人不明显。您可以通过运行 -> 使用性能工具开始从 XCode 中启动仪器。进入 Instruments 后,您可以打开 Library 并添加新插件来监控不同方面的性能。
于 2008-11-14T05:13:41.673 回答
0

要寻找的一件事是循环引用。

(我不希望这听起来很傲慢——只是想确保我清楚:) 如果 object a指的是 object b而 object b指的是 object a,则可能不会报告“泄漏”,因为所有内存仍然被引用 - 但这可能是一个孤立的对象岛,与您的应用程序分离并且永远无法回收。当然它可能涉及更多的对象(abbcca,等等)。

如果您在某处构建对象图,并且有任何反向或交叉引用,请确保在释放根时打破圆圈(有不同的方法。最简单的可能是确保每个类有问题的有一个 releaseAll 方法,或类似的方法——它在它的子对象上调用 releaseAll,然后释放子对象——但这并不总是最好的解决方案)。

于 2008-11-14T09:40:03.710 回答