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

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

问题描述

我正在使用 OpenGL ES 开发一款 2D iPhone 游戏,但我一直在达到 24 MB 内存限制 - 我的应用程序不断崩溃并显示错误代码 101.我非常努力地想找到内存的去向,但 Instruments 中的数字仍然比我预期的要大得多.

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.

我使用 Memory Monitor、Object Alloc、Leaks 和 OpenGL ES 工具运行应用程序.当应用程序加载时,可用物理内存从 37 MB 下降到 23 MB,Object Alloc 稳定在 7 MB 左右,Leaks 显示两个或三个泄漏大小为几个字节,Gart 对象大小约为 5 MB,Memory Monitor 说应用程序占用大约 14 MB 的实际内存.我很困惑内存去了哪里——当我深入研究对象分配时,大部分内存都在纹理中,正如我所期望的那样.但我自己的纹理分配计数器和 Gart 对象大小都同意纹理应该占用大约 5 MB.

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.

我不知道分配任何其他值得一提的东西,并且 Object Alloc 同意.记忆去哪儿了?(如果这还不够,我很乐意提供更多细节.)

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.)

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

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?

我已经尝试过 通常 嫌疑人,即.UIImage 及其缓存,但这并没有帮助.有没有办法调试器式"逐行跟踪内存使用情况,观察每条语句对内存使用的影响?

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?

到目前为止我发现了什么:

  1. 我真的 am 使用了那么多内存.衡量真正的内存消耗并不容易,但是经过大量计算后,我认为内存消耗确实很高.我的错.

  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.

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

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.

我误读了编程指南.24 MB 的内存限制适用于纹理和表面,而不是整个应用程序.实际的红线稍远一些,但我找不到任何硬数字.共识是 25-30 MB 是上限.

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.

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

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.

推荐答案

我非常怀疑这是 Instruments 中的错误.

首先,阅读这个 博客Jeff Lamarche 发布的关于 openGL 纹理的帖子:

  • 有一个如何加载的简单示例纹理不会导致泄漏
  • 让您了解小"的程度图片,加载后获取进入openGL,实际上使用很多"内存

摘录:

纹理,即使它们是由压缩图像,大量使用你的应用程序的内存堆,因为它们必须在内存中扩展才能用过的.每个像素占用四个字节,所以忘记释放你的纹理图像数据真的会吃掉你的快速记忆.

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.

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

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.

更新:在考虑了您的问题后,我一直在阅读 Apple 的 OpenGL ES Programming Guide 里面有很好的信息.强烈推荐!

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天全站免登陆