【问题标题】:iPhone Memory Management didReceiveMemoryWarningiPhone 内存管理 didReceiveMemoryWarning
【发布时间】:2010-10-29 14:42:24
【问题描述】:

好的……

我正在 iPhone 上实现一个简单的 OpenGL ES 应用程序,并且我最近添加了 Pinch Media Analytics。这样做有助于发现内存管理问题,但我不完全确定如何处理它。

在一个完美的世界中,我的应用程序 - 在 didFinishLoading 中加载 PNG 和 .CAF 文件将启动,加载它的所有资源,并且运行良好。

但是,如果我的程序崩溃(在我集成 Pinch Media 库时发生)或者如果我运行 Safari 并打开一堆页面然后启动我的游戏,游戏将崩溃回到菜单,因为它内存不足。

在我对系统进行硬重置之前,此问题将一直存在。

您上网的默认答案是实现如下所列的 didReceiveMemoryWarning 方法....

- (void)didReceiveMemoryWarning
{ 
  // default behavior is to release the view if it doesn't have a superview.

  // remember to clean up anything outside of this view's scope, such as
  // data cached in the class instance and other global data.
  [super didReceiveMemoryWarning];
}

但这并没有真正的帮助,因为是其他程序占用了内存,而不是我的。我不想发表我自己的观点是吗?是否有关于如何处理这种情况和/或在 didReceiveMemoryWarning 事件中发生什么的详细说明?

【问题讨论】:

    标签: iphone memory-management


    【解决方案1】:

    欢迎来到没有虚拟机的共享内存池……在这里你可以做的不多,但有一些事情(这实际上可能是你的错,你可以完全修复它)。出于这个原因,游戏开发人员经常建议他们的客户在运行它们之前重新启动,因此如果您确实需要大量内存才能发挥作用,您可能需要同舟共济。

    当然,您应该尽量减少自己的内存占用。但是你也应该尽量避免过多的内存碎片。有时问题不在于没有记忆;只是没有足够大的块。有时最好使用 Mutable 并不断修改它,而不是生成新的不可变对象。对于大型 NSString 尤其如此,它确实会浪费内存。

    请记住,UIImage +imageNamed: 会在您释放图像后保留它,因此如果您不再需要它们,则需要清除它们。在释放它之前将其名称设置为 nil 以停止缓存。

    确保在 Instruments 下运行您的应用。您消耗的内存可能比您想象的要多。

    不要忘记自动释放池。如果您在单个事件循环中生成大量自动释放的对象,您可能需要定期排空池,以免内存激增。内存峰值可能会导致内存需求适中的程序突然被终止。

    【讨论】:

    • 谢谢罗伯。我会试一试。
    • 当你说“在仪器下运行你的应用程序”时,最有趣的衡量标准是“Live Bytes”吗?
    • 我通常使用分配工具,将“Created & Still Living”作为 Lifespan(这是默认设置)。我还特别喜欢将 Track Display(单击“i”)样式切换为“Allocation Density”。这基本上为您提供了所用字节数的一阶导数,这使您可以轻松找到您突然分配大量内存的位置。
    【解决方案2】:

    如果你只有一个视图,那么你唯一能做的就是释放任何你不使用的数据,然后延迟加载它们。

    如果您有多个视图,那么如果它们不可见,它们可能会被释放。如果发生这种情况,相应的控制器将被发送setView:nil。我通过立即释放所有IBOutlet 变量来处理这种情况,以便在再次从xib 加载视图时正确设置它们。

    这是我在普通的非 OpenGL ES 应用程序中采用的方法,该应用程序具有 >6 个视图,并且即使我在导航视图中的 4 级深度并且所有以前的控制器都将其视图设置为 nil 时也能始终如一地工作- 当我向后导航时没有崩溃,尽管在重新加载视图时会有延迟。

    如果您还没有找到它,在模拟器中有一个菜单项可以模拟内存警告,这比在真实设备中强制条件发生更容易。也就是说,它并不能取代在真实设备中测试相同场景 - 只是让测试更容易。

    【讨论】:

    • 谢谢。我会尝试延迟加载方法,因为它只有一个视图。
    【解决方案3】:

    您可以尝试使用压缩的 PVRTC 而不是 PNG,以节省一些空间(可能会降低性能)。

    这里有一个不错的小教程:

    http://iphonedevelopment.blogspot.com/2008/12/preparations-for-porting-nehe-lesson-06.html

    请记住,您必须重写一些 OpenGL 调用来处理这种不同的压缩纹理。

    [免责声明:我不是 OpenGL ES 优化大师。不是一个很长的镜头。]

    【讨论】:

      猜你喜欢
      • 2011-04-10
      • 2011-10-10
      • 2010-10-28
      相关资源
      最近更新 更多