我认为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();
如您所见,我在加载字体之前输出了一些内存信息。然后我创建了2,000个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()),结果为true,因此dispose方法也应该处理创建的字体纹理。
我知道JVM使用一些RAM,这就是为什么任务管理器显示比代码中大的数字。但为什么最终使用的Java堆内存增加了94MB (122-28),进程内存增加了175MB (340-165)呢?
我是在错误地加载或释放东西吗?是Java的问题还是LibGDX的问题?这是一个严重的问题,因为在我的程序的某个部分,我需要加载和卸载很多字体...
更新:
我跳过了数组部分: 我创建了字体bitmapFont,然后立即调用了bitmapFont.dispose()和bitmapFont=null。进程内存没有改变,使用的堆空间也保持不变。为什么?!
我正在运行Windows 7,Java 7。