触发释放内存的释放?
Posted
技术标签:
【中文标题】触发释放内存的释放?【英文标题】:Trigger the release of released memory? 【发布时间】:2011-12-01 17:17:36 【问题描述】:我的应用在使用“快速”或说“稳定”时由于内存不足问题不断崩溃。
应用程序本身由许多屏幕组成,上面有很多分层图形。 为了不将太多数据加载到内存中,我在用户离开一个屏幕时释放所有加载的内容,然后开始加载下一屏幕的图形并显示它们。
在大多数情况下效果很好,但有一种方法可以让应用程序崩溃,我不知道如何防止它。
如果用户不停地从一个屏幕导航到另一个屏幕,没有真正的暂停,那么即使对象被释放或至少调用了释放方法,内存也没有被释放。内存越来越满,直到用户停止滑动或应用崩溃。
当我使用仪器(以及显示可用物理内存的屏幕显示器)监控内存使用情况时,我发现一旦用户停止,应用程序处于空闲状态,大约需要 5 到 10 秒,然后是一大块物理内存立即释放。就像我的 iPad 上高达 90MB 一样。
我非常有信心没有剩余对对象的引用。如果引用仍然存在,则它们不会在几秒钟后被卸载。所以我对如何改进这件事没有真正的想法。
有没有办法告诉设备真正释放“释放”的内存?或者,除了为所有对象调用 release 并确保没有剩余引用之外,我还需要做一些“额外”的事情吗?
更新
我在 cocoabuilder.com 上的帖子中发现了可能是什么原因的线索。那里说从视图中删除的层实际上并没有立即释放,而是延迟了 6 到 10 秒。什么与我看到的延迟完全匹配。这也很有意义。
由于图层包含对图像的引用 (.contents),因此存在一个活动引用,将图像保存在内存中,直到图层最终被释放。
我试图通过设置.contents = nil
来删除引用,但这并没有解决问题。仍然缺少一些我没有看到的东西。
【问题讨论】:
我怀疑你并不像你应该理解的那样理解 Cocoa 内存管理。你读过Apple's memory management guide吗? 这是一个有效的假设;)。但在我发布我的问题之前,我确实阅读了该指南,而且我在最近的技术谈话中听到了关于 ARC、MMR 和性能会议的会议。让我感到困惑的是,如果我用仪器看到的东西是正确的(我认为它是正确的),几乎每个应用程序都应该以相同的方式工作,因此应该有同样的问题。所以应该有一个相当普遍的解决方案。但如果有的话,我找不到它...... 【参考方案1】:也许您应该考虑使用-[NSAutoreleasePool drain]
,它“如果自上次收集后分配的内存大于当前阈值,则触发垃圾收集。”
更新使用release
而不是autorelease
也是明智之举。正如您所观察到的,一个会立即触发,另一个需要几秒钟。
【讨论】:
感谢您的建议。我做了一些更改以使用发布而不是自动发布,但它并没有解决问题。 你不能只使用-drain
willy-nilly。它必须在您在代码中创建的自动释放池的上下文中使用,并且一旦使用,该池就无效。【参考方案2】:
如果您正在释放对象,但没有发现正在释放的内存,那么您就过度保留了您的对象,而实际上并未完全释放它们。您正在经历的是大量的内存泄漏。尝试在 Instruments 下运行您的应用并使用 Leaks 工具。
【讨论】:
内存实际上被释放了,只是不是马上。所以我假设这不是一个过度保留的问题或泄漏,我找不到仪器的泄漏。以上是关于触发释放内存的释放?的主要内容,如果未能解决你的问题,请参考以下文章
为啥有时会立即释放内存,而有时仅在自动释放池耗尽时才释放内存?