【发布时间】:2014-07-18 20:59:01
【问题描述】:
我目前正在使用 libGDX 开发游戏;但是,在我的两台不同设备上运行它时,内存使用量存在巨大差异。
我目前正在使用 HTC One X+ 和 Nexus 7 进行测试。在测试时,我注意到 Nexus 7 的堆大小更大,并且使用了更多的堆。在使用 Android 设备监视器查看它时,我注意到设备之间的 1 字节数组完全不同(6 MB 与 48 KB),而其他一切都非常相似。
我认为问题在于纹理和设备之间的不同分辨率(1280x720 与 1920×1200)以及 libGDX 如何存储信息。尽管与普通的 Android 编程不同,没有办法拥有不同的纹理集(drawable-hdpi 与 drawable-xxhdpi),因为它们都位于 assets 文件夹中。
如何改进当前使用的内存?
以下是我一直在研究的一些数据。这只是坐在主菜单上,显示 2 个纹理,没有任何更新。
HTC One X+ 堆 - 62.70% 已使用(1280 x 720)
Nexus 7 堆 - 94.53% 已使用(1920 x 1200)
数据比较
Nexus 7 (vs) HTC One X+
堆:9.6 MB(对比)4.8 MB
已分配:9.1 MB(对比)3.0 MB
免费:537 KB(对比)1.8 MB
已使用:94.53%(对比)62.70%
对象:48,024 (vs) 46,012
免费:402 KB(对比)1.8 MB
数据:914 KB(对比)860 KB
类:1 MB(对比)1.1 MB
1 字节:6 MB(对比)48.6 KB
2 字节:705 KB(对比)633 KB
4 字节:399 KB(对比)405 KB
8 字节:9.3 KB(对比)6 KB
非 Java : 70 KB (vs) 6 KB
Logcat(经常调用垃圾收集器。)
07-19 05:39:09.651 6453-6469/com.mygdx.game.android D/dalvikvm﹕GC_FOR_ALLOC 释放 524K,7% 释放 9442K/10128K,暂停 19ms,总共 20ms
07-19 05:39:12.644 6453-6469/com.mygdx.game.android D/dalvikvm﹕GC_FOR_ALLOC 释放 512K,7% 释放 9442K/10128K,暂停 18ms,总共 18ms
07-19 05:39:15.657 6453-6469/com.mygdx.game.android D/dalvikvm:GC_FOR_ALLOC 释放 512K,7% 释放 9442K/10128K,暂停 24ms,总共 25ms
07-19 05:39:18.660 6453-6469/com.mygdx.game.android D/dalvikvm:GC_FOR_ALLOC 释放 511K,7% 释放 9442K/10128K,暂停 24ms,共 24ms
编辑:
我在 Android Studio (Beta) 0.8.0 中使用 LibGDX Setup App 创建了一个新项目。 对代码的唯一更改是 build.gradle:
classpath 'com.android.tools.build:gradle:0.12.+'
而不是
classpath 'com.android.tools.build:gradle:0.10+'
它目前仍在使用 Nexus 7 上 96% 的堆空间。
public class myGame extends ApplicationAdapter {
SpriteBatch batch;
Texture img;
@Override
public void create () {
batch = new SpriteBatch();
img = new Texture("badlogic.jpg");
}
@Override
public void render () {
Gdx.gl.glClearColor(1, 0, 0, 1);
Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT);
batch.begin();
batch.draw(img, 0, 0);
batch.end();
}
}
【问题讨论】:
-
你可以提示,但不要控制垃圾回收。您遇到的实际问题是什么?
-
问题是在 Nexus 7 上,垃圾收集器被相当频繁地调用,这导致了帧率问题。而在 HTC One X+ 等分辨率较低的设备上,我没有任何垃圾收集调用。
-
在这种情况下,请确保没有要收集的 GC。例如。不要在
render等经常调用的方法中创建对象。还要记住,字符串连接之类的东西(例如"score: "+score)可能会导致GC启动,请改用StringBuilder。 -
但问题是我实际上还没有创建任何东西。我所做的测试是在一个只有 2 个纹理(背景和标题)的主菜单上进行的。在我的 Nexus 7 上,我什至在创建任何对象之前就已经使用了大部分堆。
-
显然有对象经常被创建,否则GC不会收集任何东西。考虑展示实际的代码,否则就很难说更多了。