带有LibGDX字体内存泄漏的Java

带有LibGDX字体内存泄漏的Java,java,memory,memory-leaks,libgdx,Java,Memory,Memory Leaks,Libgdx,我认为在LibGDX中处理位图字体有问题。 我创建了这个测试: printAnalytics(); ArrayList<BitmapFont> fonts = new ArrayList<BitmapFont>(); for (int i = 0; i < 2000; i++) { // create a sample parameters FreeTypeFontParameter params = new FreeTypeFontParameter()

我认为在LibGDX中处理位图字体有问题。 我创建了这个测试:

printAnalytics();

ArrayList<BitmapFont> fonts = new ArrayList<BitmapFont>();
for (int i = 0; i < 2000; i++) {
  // create a sample parameters
  FreeTypeFontParameter params = new FreeTypeFontParameter();
  params.size = 12;
  params.minFilter = TextureFilter.Nearest;
  params.magFilter = TextureFilter.Nearest;

  // load the font
  FileHandle fontFile = Gdx.files.internal("arial.ttf");

  // generate it
  FreeTypeFontGenerator generator = new FreeTypeFontGenerator(fontFile);
  BitmapFont bitmapFont = generator.generateFont(params);
  bitmapFont.setUseIntegerPositions(false);
  generator.dispose();

  // add to array
  fonts.add(bitmapFont);
}

printAnalytics();
// dispose all fonts
for (BitmapFont font : fonts) {
  font.dispose();
}
// clear array
fonts.clear();
fonts = null;

printAnalytics();
以下是我的输出:

***** Heap utilization statistics [MB] *****

Total Memory: 120
Free Memory: 91
Used Memory: 28
Max Memory: 1790
Gdx Java Heap: 28
Gdx Native Heap: 28

***** Heap utilization statistics [MB] *****

Total Memory: 232
Free Memory: 109
Used Memory: 122
Max Memory: 1790
Gdx Java Heap: 122
Gdx Native Heap: 122

***** Heap utilization statistics [MB] *****

Total Memory: 232
Free Memory: 109
Used Memory: 122
Max Memory: 1790
Gdx Java Heap: 122
Gdx Native Heap: 122
以及任务管理器中的数字:

  • 测试前:165 MB(我正在测试我的一个应用程序)
  • 加载字体后:800 MB
  • 处理后:340MB
您可以看到问题:测试前后使用的内存应该相同。但事实并非如此。它是+150/200 MB

我检查了BitmapFont是否拥有纹理(font.ownsTexture()),这是真的,因此dispose方法也应该处理创建的字体纹理

我知道JVM使用了一些RAM,这就是为什么TaskManager显示的数字比代码中的数字要大。但为什么最终使用的java堆是+94MB(122-28),进程内存是+175MB(340-165)

我装错东西了吗?是Java吗?是LibGDX吗?这是一个严重的问题,因为在我的程序的一部分,我需要加载和卸载很多字体

更新:

我跳过了数组的部分:我创建了字体bitmapFont,然后立即调用bitmapFont.dispose()和bitmapFont=null。进程内存没有改变,堆使用的空间也保持不变。为什么


我运行的是Windows 7,Java 7。

有趣的问题,我对您的测试做了一些更改,基本上将不属于测试本身的所有内容(如字体加载、参数)移到了循环之外。我还添加了前后的System.gc()调用,以便我们可以看到正在使用的实际内存

            printAnalytics("before test");

            Array<BitmapFont> fonts = new Array<BitmapFont>();
            // create a sample parameters
            FreeTypeFontGenerator.FreeTypeFontParameter params = new FreeTypeFontGenerator.FreeTypeFontParameter();
            params.size = 12;
            params.minFilter = Texture.TextureFilter.Nearest;
            params.magFilter = Texture.TextureFilter.Nearest;

            // load the font
            FileHandle fontFile = Gdx.files.internal("arial.ttf");
            for (int i = 0; i < 2000; i++) {
                // generate it
                FreeTypeFontGenerator generator = new FreeTypeFontGenerator(fontFile);
                BitmapFont bitmapFont = generator.generateFont(params);
                bitmapFont.setUseIntegerPositions(false);
                generator.dispose();

                // add to array
                fonts.add(bitmapFont);
            }

            printAnalytics("before disposing, before first gc");
            System.gc();
            printAnalytics("before disposing, after first gc");
            // dispose all fonts
            for (BitmapFont font : fonts) {
                font.dispose();
            }
            // clear array
            fonts.clear();
            printAnalytics("after disposing, before second gc");
            System.gc();
            printAnalytics("after disposing, after second gc");
以下是我的结果:

***** Heap utilization (before test) statistics [MB] *****

Total Memory: 180
Free Memory: 165
Used Memory: 15
Max Memory: 2647
Gdx Java Heap: 15
Gdx Native Heap: 15

***** Heap utilization (before disposing, before first gc) statistics [MB] *****

Total Memory: 180
Free Memory: 101
Used Memory: 78
Max Memory: 2647
Gdx Java Heap: 78
Gdx Native Heap: 78

***** Heap utilization (before disposing, after first gc) statistics [MB] *****

Total Memory: 180
Free Memory: 132
Used Memory: 48
Max Memory: 2647
Gdx Java Heap: 48
Gdx Native Heap: 48

***** Heap utilization (after disposing, before second gc) statistics [MB] *****

Total Memory: 180
Free Memory: 131
Used Memory: 48
Max Memory: 2647
Gdx Java Heap: 48
Gdx Native Heap: 48

***** Heap utilization (after disposing, after second gc) statistics [MB] *****

Total Memory: 180
Free Memory: 178
Used Memory: 2
Max Memory: 2647
Gdx Java Heap: 2
Gdx Native Heap: 2

看起来处理会有所不同,但看起来java将决定何时释放内存,除非调用System.gc()

Cool man。我测试了它-你是对的,gc完成了任务:)奇怪的是任务管理器中的内存仍然保持不变-300MB
    public static void printAnalytics(String event) {
        ...
        System.out.println("\n***** Heap utilization (" + event + ") statistics [MB] *****\n");
***** Heap utilization (before test) statistics [MB] *****

Total Memory: 180
Free Memory: 165
Used Memory: 15
Max Memory: 2647
Gdx Java Heap: 15
Gdx Native Heap: 15

***** Heap utilization (before disposing, before first gc) statistics [MB] *****

Total Memory: 180
Free Memory: 101
Used Memory: 78
Max Memory: 2647
Gdx Java Heap: 78
Gdx Native Heap: 78

***** Heap utilization (before disposing, after first gc) statistics [MB] *****

Total Memory: 180
Free Memory: 132
Used Memory: 48
Max Memory: 2647
Gdx Java Heap: 48
Gdx Native Heap: 48

***** Heap utilization (after disposing, before second gc) statistics [MB] *****

Total Memory: 180
Free Memory: 131
Used Memory: 48
Max Memory: 2647
Gdx Java Heap: 48
Gdx Native Heap: 48

***** Heap utilization (after disposing, after second gc) statistics [MB] *****

Total Memory: 180
Free Memory: 178
Used Memory: 2
Max Memory: 2647
Gdx Java Heap: 2
Gdx Native Heap: 2