我认为在LibGDX中处理BitmapFonts存在问题。 我创建了这个测试:
gcloud preview app deploy
正如您所看到的,我在加载字体之前输出了一些内存信息。然后我创建2 000个BitmapFonts并再次输出信息。处理字体,销毁数组(丢失所有实例)和内存信息。 我使用默认的arial字体进行测试。
以下是printAnalytics方法的代码:
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();
这是我的输出:
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));
}
来自任务管理器的数字:
您可以看到问题:此测试之前和之后使用的内存应该相同。但事实并非如此。它是+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上运行。
答案 0 :(得分:3)
有趣的问题,我改变了一点你的测试,基本上移动了所有不属于测试本身的东西,比如字体加载,参数,循环外。我之前和之后都添加了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()