iOS:ARC,不释放内存

Posted

技术标签:

【中文标题】iOS:ARC,不释放内存【英文标题】:iOS : ARC, not freeing memory 【发布时间】:2012-03-18 18:09:16 【问题描述】:

我的 ios 应用出现了一个奇怪的问题。 过了一会儿,我的应用程序内存不足,所以内存警告,一切似乎都很好,但是当我检查内存使用情况时,我注意到所有对 viewDidUnload 的调用都没有释放大量内存,所以在我的点击几下后应用程序,它再次出现内存警告,一切似乎又好了,但没有释放很多内存,所以它再次进入内存警告更快,然后它崩溃(大部分时间在第三次内存警告之后) .这个崩溃是随机的:应用程序冻结,应用程序离开,我的调试器说应用程序暂停,但没有错误的访问或 sigbort,没有僵尸。 我的猜测是内存警告无法释放足够的内存。

(我检查了我所有的 viewDidUnload 并将 viewDidLoad 中分配的每个对象设为 nil)

任何帮助都会很有用!

非常感谢。

【问题讨论】:

注释:我的代码使用了大量下载的图像。 您的应用程序中可能有循环引用,但实际上无法从这个描述中看出。 ARC 很棒,但它不是魔法。 这是一个想法,我会检查一下,谢谢 祝你好运。 :) 我刚刚发现了这一点,这就是为什么我要评论一个旧线程。 viewDidUnload 自 iOS 6 起已弃用,并且不保证会被调用(根据我的经验,大多数时候都不会调用它)。 【参考方案1】:

如果没有更多数据,我认为没有任何方法可以给出具体的答案,所以我能做的最好的事情就是建议您停止猜测您的应用可能会发生什么,并学习如何衡量实际发生的情况。在 Instruments 下运行您的应用程序,您将能够检查是否存在泄漏,还可以实际查看哪些类对您的应用程序的大部分内存占用负责。

您应该确保您知道如何使用 Leaks 工具来识别泄漏的对象,以及如何使用 Allocations 工具来识别应该被释放的孤立(但未泄漏)对象集,或者只是您的应用没有响应的情况记忆警告,如你所料。

https://developer.apple.com/library/ios/#documentation/developertools/conceptual/InstrumentsUserGuide/AboutTracing/AboutTracing.html 可能是一个不错的起点,而且还有许多可用的教程; http://www.raywenderlich.com/2696/how-to-debug-memory-leaks-with-xcode-and-instruments-tutorial 和 http://www.friday.com/bbum/2010/10/17/when-is-a-leak-not-a-leak-using-heapshot-analysis-to-find-undesirable-memory-growth/ 是我看到的第一个结果。

【讨论】:

我是否说过,我没有僵尸,没有使用仪器测量的泄漏。@"分配仪器来识别应该被释放的孤立(但未泄漏)对象集,或者只是您的应用程序所在的情况没有像您预期的那样响应内存警告。”我不知道该怎么做... 我用的是ARC,所以raywenderlich和friday.com教程都没用。【参考方案2】:

瓦西里,

首先,如果你自己没有释放额外的内存,-didReceiveMemory 警告对你没有好处,操作系统会一直请求内存,直到你被杀。这听起来像是你的问题。

其次,如果这不是问题,那么由于驻留内存分区的大小,您可能会被终止。确保查看 Instruments 中的 VM 分配。我希望 MALLOC_TINY 或 MALLOC_SMALL 都具有大于 5 MB 的常驻和脏足迹。由于小分配的性质,这些 VM 区域永远不会缩小。您真正拥有的唯一选择是首先不要创建很多小项目。这实际上只有您可以通过更改代码的算法以使用更少的内存来解决。

安德鲁

【讨论】:

- 如何在 ARC 项目中释放内存?我有很多 ViewControllers 我分配然后推入我的导航堆栈,在 ARC 之前,我曾经在弹出时释放并设置为零这个控制器,但现在有了 ARC,我不能再这样做了。我知道我不再需要这个控制器了,但是在下一次内存警告之前我无法驾驭它们。有没有办法强制释放?我会检查 MALLOC_TINY/SMALL,谢谢你的帮助。 Vassily,您可以通过将存储空间设置为 nil 来释放 ARC 中的项目。基本上,您是在告诉编译器您不再保留对该项目的引用。安德鲁 好吧,这就是我正在做的事情。例如:我分配了一个我呈现模式的视图控制器,在解雇时我将此控制器设置为 nil。这应该释放模态视图控制器占用的所有内存,但是当我分析我的应用程序时它不会。 Vassily,你分配了什么样的视图控制器?它有网页视图吗?如果内存没有被释放,那么你可能有一些保留周期。明智地使用弱引用将解决这个问题。安德鲁 是的,它有网页浏览量。我分配然后推送的总是相同的vc。 (不同的内容但相同的视图控制器)【参考方案3】:

所以我设法解决了我的问题。

我在所有控制器中都写了“-(void) dealloc”方法,并检查我是否按我应该的方式输入了它。 (在弹出控制器上,解雇等)

每次不成功时,我都会在控制器中一步一步地查看是什么阻止了我的控制器从蜂房释放。

大部分时间是一些不在“unsafe_unretained”中的属性 在“ASSIGN”中的委托(不应该在分配中,而是在 unsafe_unretained 中) (来自非 ARC 项目的遗产......)

我也有一些奇怪的带有 XIB 的控制器,即使是空的也没有被释放。 我用复制/粘贴一步一步地重建新的,最后用完全相同的代码,新的控制器被释放了,那时没有明显的区别!!! gnnee

至少我现在知道如何调试这类问题了...

【讨论】:

以上是关于iOS:ARC,不释放内存的主要内容,如果未能解决你的问题,请参考以下文章

iOS UIImageView 内存没有在 ARC 上被释放

为啥 ARC 在 popViewController 之后不释放内存

iOS 内存管理

oc56--ARC多个对象的内存管理

iOS 7 Sprite Kit 释放内存

使用 ARC 时还需要释放内存吗? [复制]