8

在使用 libGDX 开发 2D 游戏时,我遇到了一些内存消耗问题。

这是一款具有丰富图形内容的 2D 游戏 - 有许多纹理、动画、字体等。由于某些原因,所有图形内容都在游戏开始时加载 - 这是内存问题。我已经在不同的设备上测试了内存分配(本机和堆)并得到了不同的结果:(我已经将所有设备按纹理大小划分为组)

第 1 组(~840*480 屏幕采用的纹理)

HTC Desire (Froyo): 178Mb(native) - 12Mb(heap) -应用程序加载成功

HTC One V (ICS): 30Mb(native) - 12Mb(heap) -应用程序加载成功

HTC Desire S (Jelly Bean): 30Mb(native) - 12Mb(heap) -应用程序加载成功

第 2 组(~1366*768 屏幕采用的纹理)

Samsung(Google) Galaxy Nexus 329Mb(native) - 18Mb(heap) -完美运行

Galaxy TAB (Honeycomb) 164Mb(native) - 10Mb(heap) -应用程序崩溃(Surface.OutOfResouresException)。

我认为所有 android 版本可能存在一些显着的内存管理差异,这给我带来了这些麻烦。

谁能解释在 android 3.x 上加载纹理时到底发生了什么?或者可能发布一些链接以了解解决此问题需要做些什么。

一些更新

今天我在 3.x 模拟器上做了一些额外的测试(我知道这不是最好的方法,但是之前在 emu 和 Galaxy Tab 上的日志是相似的)

  1. 我运行的游戏采用 1024*600 的纹理 - 应用程序在 80% 的加载资源(158 个本机内存分配)上崩溃
  2. 使用 800*480 的纹理 - 应用程序在 100% 加载时崩溃(145Mb 本机内存分配)

最后,我在新的 Google Nexus 平板电脑(Jelly Bean)上运行了应用程序,它使用与 3.x 平板电脑(1280*800px)相同的纹理 - ~30Mb 本机内存和 ~12Mb 虚拟机堆。

现在我完全不理解发生了什么——纹理 800*480 和 1280*800 的内存分配相同......

最后

我一直在使用带有一些进度条的按需加载资源来解决这种情况。经过所有尝试,我没有找到另一种方法。

4

2 回答 2

3

如果您想知道为什么 Android 3 崩溃超过 2.X,那是因为 ByteBuffer 错误。ByteBuffer 使用 4 倍的内存。所以你必须为 Android 3 使用较低分辨率的图像。这在 Android 4 中得到了解决。

http://code.google.com/p/android/issues/detail?id=16941

幸运的是 Android 3+ 你有大堆选项(提供大约 128+ 兆),这是我必须为我们的应用程序打开的。

于 2012-10-14T21:36:47.493 回答
1

我相信如果位图的格式与显示的格式不匹配,位图的运行时内存使用量可能会膨胀(系统最终将创建一个具有正确格式的副本以进行 blit)。我认为这在较旧的 Android 系统上更多是一个问题,可能不是您在 3.0 上看到的,但可能值得研究。(请参阅Romain 帖子末尾的性能位)

在 3.0 (Honeycomb) 中,位图底层字节数组的内存占位图发生了变化,内存从本机端移动到 Java 堆。但是,这只是转移了内存,并且不应该影响实际限制(本机内存仍然计入相同的限制,它只是对某些工具不可见)。

不同设备上的堆限制也不同。(请参阅不同手机/设备和操作系统版本上的 Android 堆大小

这个 Google I/O 演讲涵盖了一系列可能有用的关于 3.0 中内存管理更改的问题:http: //dubroy.com/blog/google-io-memory-management-for-android-apps/

您可以在内存较低的设备上加载位图的缩小版本。它可能也值得阅读http://developer.android.com/training/displaying-bitmaps/index.html的其余部分。

您的应用程序有多少磁盘图像数据?您正在加载的其他非图像数据(字体、动画等)有多大?

于 2012-10-02T16:21:22.387 回答