了解iPhone上的内存消耗 [英] Understanding the memory consumption on iPhone

查看:122
本文介绍了了解iPhone上的内存消耗的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在开发使用OpenGL ES的2D iPhone游戏,并且我一直在达到24 MB的内存限制 - 我的应用程序一直在崩溃,错误代码为101.我真的很难找到内存的位置,但是仪器中的数字仍然比我预期的要大得多。



我使用Memory Monitor,Object Alloc,Leaks和OpenGL ES仪器运行应用程序。当应用程序加载时,自由物理内存从37 MB下降到23 MB,Object Alloc稳定在7 MB左右,泄漏显示两个或三个泄漏,几个字节大小,Gart对象大小约为5 MB,内存监视器说应用程序占用大约14 MB的实内存。令我感到困惑的是内存的去向 - 当我深入研究对象分配时,大部分内存都在纹理中,正如我所期望的那样。但是我自己的纹理分配计数器和Gart对象大小都认为纹理应该占用大约5 MB。



我不知道分配任何其他的东西值得一提的是,Object Alloc同意。记忆在哪里? (如果这还不够,我会很乐意提供更多细节。)






更新:我真的试图找到可以分配如此多内存的地方,但没有结果。让我疯狂的是对象分配(~7 MB)与内存监视器(~14 MB)所示的实际内存使用之间的差异。即使存在巨大的泄漏或我忘记的大量内存,仍应出现在对象分配中,不应该出现吗?



<我已经尝试了通常 嫌犯,即。带有缓存的 UIImage ,但这没有帮助。有没有办法逐行跟踪内存使用情况调试器样式,观察每个语句对内存使用情况的影响?






到目前为止我找到了什么:


  1. 我真的 am 使用那么多记忆。测量实际内存消耗并不容易,但经过大量计算后,我认为内存消耗确实很高。我的错。


  2. 我发现没有简单的方法来测量使用的内存。内存监视器编号是准确的(这些是真正重要的数字),但内存监视器无法告诉您内存的确切位置。 Object Alloc工具几乎无法跟踪实际内存使用情况。当我创建一个纹理时,分配的内存计数器会上升一段时间(将纹理读入内存),然后下降(将纹理数据传递给OpenGL,释放)。这没关系,但并不总是发生 - 有时即使纹理传递给OpenGL并从我的内存中释放出来,内存使用率也会保持很高。这意味着Object Alloc工具显示的内存总量小于实际总内存消耗,但大于实际消耗量减去纹理( real - textures< object alloc< real )。去图。


  3. 我误读了编程指南。内存限制为24 MB适用于纹理和曲面,而不是整个应用程序。实际的红线有点进一步,但我找不到任何硬数字。一致意见是25-30 MB是上限。


  4. 当系统内存不足时,它开始发送内存警告。我几乎没有什么可以免费的,但其他应用程序确实会释放一些内存回系统,特别是Safari(似乎是缓存网站)。当内存监视器中显示的可用内存为零时,系统开始查杀。


我不得不咬bullet并重写代码的某些部分以提高内存的效率,但我可能仍在推动它。如果我要设计另一个游戏,我肯定会考虑一些资源分页。在当前的游戏中它非常难,因为事物一直处于运动中并且加载纹理会妨碍,即使在另一个线程中完成。 我会对其他人如何解决这个问题感兴趣。



请注意,这些只是我的意见,不一定要多准确。如果我发现有关此主题的更多内容,我会更新问题。我会保持问题公开,以防有人理解这个问题会关心回答,因为这些都是比其他任何事情更多的变通办法和猜测。

解决方案

我非常怀疑这是仪器中的一个错误。



首先,请阅读 Jeff Lamarche关于openGL纹理的博客文章




  • 有一个简单的例子,说明如何在不造成泄漏的情况下加载
    纹理

  • 让我们了解如何小
    图片,一旦将它们加载到openGL中
    ,实际上使用很多内存



摘录:


纹理,即使它们来自
压缩图像,也会使用大量的
应用程序的内存堆因为
必须在内存中扩展为
。每个像素占用四个字节,
因此忘记释放纹理
图像数据可以快速耗尽你的
内存。


其次,可以使用Instruments调试纹理内存。有两种配置文件配置: OpenGL ES Analyzer OpenGL ES驱动程序。您需要在设备上运行这些,因为模拟器不使用OpenGL。只需从XCode中选择产品 - >配置文件,并在仪器启动后查找这些配置文件。






有了这些知识,这里是我会做什么:




  • 检查你是不是内存泄漏 - 这显然会导致这个问题。

  • 确保你没有访问自动释放的内存 - - 崩溃的常见原因。

  • 创建一个单独的测试应用程序,并单独(和组合)加载纹理,以找出导致问题的纹理(或其组合)。



UPDATE:在考虑了你的问题后,我一直在阅读 Apple的OpenGL ES编程指南,它有非常好的信息。强烈推荐!


I am working on a 2D iPhone game using OpenGL ES and I keep hitting the 24 MB memory limit – my application keeps crashing with the error code 101. I tried real hard to find where the memory goes, but the numbers in Instruments are still much bigger than what I would expect.

I ran the application with the Memory Monitor, Object Alloc, Leaks and OpenGL ES instruments. When the application gets loaded, free physical memory drops from 37 MB to 23 MB, the Object Alloc settles around 7 MB, Leaks show two or three leaks a few bytes in size, the Gart Object Size is about 5 MB and Memory Monitor says the application takes up about 14 MB of real memory. I am perplexed as where did the memory go – when I dig into the Object Allocations, most of the memory is in the textures, exactly as I would expect. But both my own texture allocation counter and the Gart Object Size agree that the textures should take up somewhere around 5 MB.

I am not aware of allocating anything else that would be worth mentioning, and the Object Alloc agrees. Where does the memory go? (I would be glad to supply more details if this is not enough.)


Update: I really tried to find where I could allocate so much memory, but with no results. What drives me wild is the difference between the Object Allocations (~7 MB) and real memory usage as shown by Memory Monitor (~14 MB). Even if there were huge leaks or huge chunks of memory I forget about, the should still show up in the Object Allocations, shouldn’t they?

I’ve already tried the usual suspects, ie. the UIImage with its caching, but that did not help. Is there a way to track memory usage "debugger-style", line by line, watching each statement’s impact on memory usage?


What I have found so far:

  1. I really am using that much memory. It is not easy to measure the real memory consumption, but after a lot of counting I think the memory consumption is really that high. My fault.

  2. I found no easy way to measure the memory used. The Memory Monitor numbers are accurate (these are the numbers that really matter), but the Memory Monitor can’t tell you where exactly the memory goes. The Object Alloc tool is almost useless for tracking the real memory usage. When I create a texture, the allocated memory counter goes up for a while (reading the texture into the memory), then drops (passing the texture data to OpenGL, freeing). This is OK, but does not always happen – sometimes the memory usage stays high even after the texture has been passed on to OpenGL and freed from "my" memory. This means that the total amount of memory allocated as shown by the Object Alloc tool is smaller than the real total memory consumption, but bigger than the real consumption minus textures (real – textures < object alloc < real). Go figure.

  3. I misread the Programming Guide. The memory limit of 24 MB applies to textures and surfaces, not the whole application. The actual red line lies a bit further, but I could not find any hard numbers. The consensus is that 25–30 MB is the ceiling.

  4. When the system gets short on memory, it starts sending the memory warning. I have almost nothing to free, but other applications do release some memory back to the system, especially Safari (which seems to be caching the websites). When the free memory as shown in the Memory Monitor goes zero, the system starts killing.

I had to bite the bullet and rewrite some parts of the code to be more efficient on memory, but I am probably still pushing it. If I were to design another game, I would certainly think of some resource paging. With the current game it’s quite hard, because the thing is in motion all the time and loading the textures gets in the way, even if done in another thread. I would be much interested in how other people solve this issue.

Please note that these are just my views that do not have to be much accurate. If I find out something more to say on this topic, I will update the question. I’ll keep the question open in case somebody who understands the issue would care to answer, since these all are more workarounds and guesses than anything else.

解决方案

I highly doubt this is a bug in Instruments.

First, read this blog post by Jeff Lamarche about openGL textures:

  • has a simple example of how to load textures without causing leaks
  • gives understanding of how "small" images, get once they are loaded into openGL, actually use "a lot" of memory

Excerpt:

Textures, even if they're made from compressed images, use a lot of your application's memory heap because they have to be expanded in memory to be used. Every pixel takes up four bytes, so forgetting to release your texture image data can really eat up your memory quickly.

Second, it is possible to debug texture memory with Instruments. There are two profiling configurations: OpenGL ES Analyzer and OpenGL ES Driver. You will need to run these on the device, as the simulator doesn't use OpenGL. Simply choose Product->Profile from XCode and look for these profiles once Instruments launches.


Armed with that knowledge, here is what I would do:

  • Check that you're not leaking memory -- this will obviously cause this problem.
  • Ensure your'e not accessing autoreleased memory -- common cause of crashes.
  • Create a separate test app and play with loading textures individually (and in combination) to find out what texture (or combination thereof) is causing the problem.

UPDATE: After thinking about your question, I've been reading Apple's OpenGL ES Programming Guide and it has very good information. Highly recommended!

这篇关于了解iPhone上的内存消耗的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆