【问题标题】:LibGDX - 1-Byte Array Size Varies On Different ResolutionLibGDX - 1 字节数组大小因不同分辨率而异
【发布时间】: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不会收集任何东西。考虑展示实际的代码,否则就很难说更多了。

标签: android libgdx textures


【解决方案1】:

您可以使用相同的工具来找出分配内存的原因。您可以回溯到有问题的代码。这应该有助于解释您的 1 字节数组的来源。 (正如 Xoppa 所说,如果你不分配东西,GC 就不会运行,所以你必须直接或间接触发分配,作为一项规则,你不希望经常运行 any 分配render) 之类的方法。

只需使用下一个标签(“分配跟踪器”)。让您的应用程序进入稳定状态(启动期间的分配还没有那么有趣)。转到选项卡,单击“开始跟踪”,等待 5-10 秒,单击“获取分配”,您应该会看到关于谁在分配内存以及为什么分配内存的非常精确的答案。见http://developer.android.com/tools/debugging/debugging-memory.html

(Nexus 7 有一个更大的堆,所以它可能只是让更多的东西在运行 GC 之前堆积在堆上,而较小的堆需要更频繁地收集,所以堆积的东西更少。)

【讨论】:

  • 我使用 Allocation Tracker 来找出为什么我在我的更新方法中有分配,并且它只是对循环施了魔法。 for( Entity e : entities ) 但问题是即使只是启动我的应用程序,我也几乎立即得到垃圾收集。例如,在我的主菜单上,我创建了一个 Player。没什么大不了的,但它说已经只剩下 5% 的堆了。这很奇怪,因为这在我的其他设备上没有发生,而且庞大的 1 字节数组仅存在于 Nexus 上。我想知道它是否正在缩放纹理并以某种方式保存它。
  • 即使在创建了一个全新的项目之后,屏幕上只显示了默认的 badlogic.jpg,它仍然占用了我 96% 的堆空间。我创建了一个讨论,link,看看为什么会这样。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-09-19
  • 2016-06-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-04
相关资源
最近更新 更多