iPhone内存管理确实收到了内存警告

iPhone内存管理确实收到了内存警告,iphone,memory-management,Iphone,Memory Management,好的 我正在iPhone上实现一个简单的OpenGL ES应用程序,最近添加了Pinch Media Analytics。这样做有助于发现内存管理问题,我不完全确定如何处理它 在一个完美的世界里,我的应用程序——在didFinishLoading中加载PNG和.CAF文件——将启动,加载它的所有资源,并正常运行 但是,如果我的程序崩溃(这是在我集成Pinch媒体库时发生的),或者如果我运行Safari并打开一堆页面然后启动游戏,游戏将崩溃回菜单,因为内存不足 在我对系统进行硬重置之前,此问题将一

好的

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

在一个完美的世界里,我的应用程序——在didFinishLoading中加载PNG和.CAF文件——将启动,加载它的所有资源,并正常运行

但是,如果我的程序崩溃(这是在我集成Pinch媒体库时发生的),或者如果我运行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事件中发生的情况,是否有一个很好的描述?

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

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

这是我在一个普通的、非OpenGL ES应用程序中采用的方法,该应用程序具有>6个视图,即使我在导航视图中有4个级别,并且所有以前的控制器都将其视图设置为
nil
——当我向后导航时不会崩溃,尽管在重新加载视图时会有延迟


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

欢迎使用没有虚拟机的共享内存池。。。。这里你能做的不多,但有几件事(可能是你的错,你可以完全修复它)。出于这个原因,游戏开发人员经常建议他们的客户在运行之前重新启动,因此如果你真的需要大量内存来提高效率,那么你可能需要与他们同舟共济

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

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

确保在Instruments下运行应用程序。你可能正在消耗比你想象的更多的记忆


别忘了自动释放池。如果在单个事件循环中生成大量自动释放的对象,则可能需要周期性地耗尽池中的内存,这样就不会占用内存。内存峰值可能会导致内存要求不高的程序突然失效。

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

这里有一个很好的小教程:

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


[免责声明:我不是OpenGL ES优化大师。不是通过长镜头拍摄的。]

谢谢。我将尝试延迟加载方法,因为它只有一个视图。谢谢Rob。我来试一试。当你说“在工具下运行你的应用程序”时,最有趣的度量是“活动字节数”吗?我通常使用“创建并仍然活动”的分配工具作为寿命(这是默认值)。我还特别喜欢将轨迹显示(单击“I”)样式切换为“分配密度”。这基本上给出了所用字节数的一阶导数,这使得很容易找到突然分配了大量内存的位置。