1

我正在制作一个必须在开始时加载所有位图的游戏,因为在内置游戏编辑器中,用户可以将任何精灵放入关卡中。关卡也使用各种精灵,没有任何系统允许为每个关卡动态加载精灵组。

一段时间后,游戏中现在已经有 250 多个 png 图像,总大小为 3.5MB。

游戏使用 BitmapFactory.decodeStream 加载大多数精灵(大约 200 个),没有设置任何选项,并且还有大约 50 个在活动的 xml 布局中引用。

当我在各种设备上测试时,游戏有时会耗尽内存,但我找不到模式,甚至决定我必须做多少,例如减少图像的大小或数量。

我开发的手机,HTC希望与Android 2.2 24MB VM堆大小永远不会运行OOM。

具有 Android 2.2 和 40MB 虚拟机堆大小的 Dell Streak 也从不运行 OOM。

具有 Android 2.1 和 24MB 虚拟机堆大小的 Motorola Milestone 成功加载了所有精灵,但在启动其中一项活动(开始菜单)时,在 ImageView 中使用的最后几张图像阻塞。如果我将其中一些这样的 ImageView 注释掉,它会加载正常,但稍后可能会因其他活动之一而窒息。它也不稳定,可能是因为碎片在不同的发布中发生的方式不同。

HTC hero 和我的好友 2.2(不知道堆大小,是 16MB 吗?)也崩溃了。

最让人迷惑的是,摩托罗拉有24MB,和HTC的愿望一样。2.1 实现内存管理的效率会降低吗?(例如导致更多碎片?)或者所有摩托罗拉手机的内存管理都更差?那么为什么HTC hero with 2.2会崩溃呢?HTC 的欲望有什么比 HTC hero 更大的呢?

看起来 OOM 发生在旧手机上,但这是我迄今为止唯一想到的。

如果 OOM 只发生在占市场 5% 的旧手机上,我可以通过收集崩溃报告并从支持列表中排除所有崩溃的设备来从支持的设备中排除 2.1 或更具体的列表。否则我现在需要将我的所有图像缩小某个常数因子(例如 1.6),这意味着调整所有 45 个级别的大小,这需要数天的设计和测试、重新定位 GUI 元素等。即使在那之后,我d 仍然不确定,在哪些设备上将位图的总大小减少 2 倍就足以避免 OOM。

对此有何建议?我应该为 BitmapFactory 设置任何特定选项吗?顺便说一句,大多数图像都有透明的 bg 像素,据我所知,这些像素不允许以 565 格式获取它们。

我花了 2 天时间在这里和其他地方浏览,但仍然不知所措。

谢谢你。

4

2 回答 2

1

我不得不处理你的问题的一个更简单的版本——我们有 3 个 2Mpix 层在彼此之上,不出所料,这有时会导致 OOM。

在我的情况下,我不是在彼此之上使用 3 个 ImageView,而是始终将所有 6 个 MPix 保留在内存中,而是手动混合了图层,因此在任何时候都在内存中最多保留 4 个 Mpix(并且只有 2 个 MPix 在“休息” - 我们的应用程序中更改的层)。

这是一个经典的时空权衡——牺牲效率(时间)来获得内存(空间)。它有点慢,因为你必须在recycle()完成每个位图后确保内存被释放。

As for the inconsistent OOMs, it probably has to do with garbage collection. You can assume that the garbage collector is non-deterministic and thus any memory pressure becomes non-deterministic as well (depending on when the GC last kicked in).

The short summary is, you have to be very, very careful with your memory usage and there's no way around it. *

* In theory, you could allocate memory outside the Dalvik heap by using the NDK and allocating straight from the OS. It's a huge hack and the bridge between Dalvik and your allocator will be rather ugly.

于 2011-10-18T15:57:33.830 回答
1

First you need to find what exactly is using all of your memory. Check this out. Maybe you could be recycling bitmaps, for instance.

于 2011-10-18T16:01:34.440 回答