我正在使用名为 LibGDX 的 Java 游戏库编写一个简单的文字游戏。
我有一个 txt 文件,包含 370k 个单词的字典,大约占用 4mb。
在我的游戏中,我使用以下代码读取了单词
wordsScored = new HashMap<>();
double start = System.currentTimeMillis() % 100000;
Gdx.app.error("1","start "+ start);
FileHandle handle = Gdx.files.internal("words.txt");
String allWordsString = handle.readString();
String wordsArray[] = allWordsString.split("\\r?\\n");
for (int i = 0; i < wordsArray.length; i++) {
String word = wordsArray[i];
wordsScored.put(word, scoreWord(word, getGameCards()));
if(i % 10000 == 0) {
Gdx.app.error("1","i="+i+" - "+ System.currentTimeMillis() % 100000);
}
}
wordsArray = null;
double end = System.currentTimeMillis() % 100000;
Gdx.app.error("1","end "+ end);
Gdx.app.error("1","total "+ (end-start));
当我在桌面上运行此程序时(您可以出于开发目的在桌面上构建),大约需要 1.5 秒才能用单词的键和分数填充 HashMap 。在 Android 上大约需要 2.5 秒。
但是,在 Android 上玩了 3-4 次之后,并且没有更改任何代码,它突然变慢了,需要 30-40 秒!
我确信我有某种内存泄漏,CV 或 Android 正在做一些疯狂的事情,比如像静态一样保留 Hashmap。
我尝试使用新的 Android studio 分析器,但这实际上使我的机器崩溃了,并且陷入了循环,而我机器上的其他所有东西都变慢了,包括鼠标等。
有谁知道我如何测试这个“泄漏”? Android 在将资源、数据从一款游戏转移到下一款游戏时是否存在任何问题? 如果 Hashmap 是一个糟糕的数据结构?
最佳答案
我可以看到您问题中的代码没有任何内存泄漏。如果您的应用程序确实存在泄漏,那么它可能位于应用程序代码的其他位置。 (例如,它可能保留对代码创建的多个 HashMap
对象的引用。您尚未向我们展示声明 wordsScored
的上下文,或解释其生命周期。 )
我承认多次运行代码会产生大量垃圾,而且问题可能与 GC 性能有关。但我认为更有可能的是您的代码中其他地方存在内存泄漏(而不是 Android ...)。
<小时/>我认为由于这一行可能存在“资源泄漏”:
FileHandle handle = Gdx.files.internal("words.txt");
但是,GDX 库似乎没有提供任何“关闭”FileHandle
的方法,因此大概没有必要这样做。
关于java - 大型 Hashmap 的 Android 性能问题,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/51736955/