gpt4 book ai didi

带有 LibGDX 字体内存泄漏的 Java

转载 作者:搜寻专家 更新时间:2023-11-01 03:00:17 27 4
gpt4 key购买 nike

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

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();

如您所见,我在加载字体之前输出了一些内存信息。然后我创建 2000 个 BitmapFonts 并再次输出信息。处理字体,销毁数组(以丢失所有实例)并再次销毁内存信息。我使用默认的 arial 字体进行测试。

这里是 printAnalytics 方法的代码:

public void printAnalytics() {
int mb = 1024 * 1024;

// get Runtime instance
Runtime instance = Runtime.getRuntime();

System.out.println("\n***** Heap utilization statistics [MB] *****\n");

// available memory
System.out.println("Total Memory: " + (instance.totalMemory() / mb));

// free memory
System.out.println("Free Memory: " + (instance.freeMemory() / mb));

// used memory
System.out.println("Used Memory: " + ((instance.totalMemory() - instance.freeMemory()) / mb));

// Maximum available memory
System.out.println("Max Memory: " + (instance.maxMemory() / mb));

// Gdx heap
System.out.println("Gdx Java Heap: " + (Gdx.app.getJavaHeap() / mb));

// Gdx heap
System.out.println("Gdx Native Heap: " + (Gdx.app.getNativeHeap() / mb));
}

这是我的输出:

***** 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
  • 处理后:340 MB

可以看到问题:这次测试前后使用的内存应该是一样的。但事实并非如此。它是 +150/200 MB!

我检查了 BitmapFont 是否拥有纹理 (font.ownsTexture()) 并且它是真的,所以 dispose 方法也应该处理创建的字体纹理。

我知道 JVM 使用一些 RAM,所以这就是为什么任务管理器显示的数字比代码中的数字大。但为什么最后使用的 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");

我对你的 printAnalytics 做了一点改动,所以它也报告了当前正在测量的事件

    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

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

关于带有 LibGDX 字体内存泄漏的 Java,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36751909/

27 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com