【发布时间】:2014-03-14 16:48:44
【问题描述】:
对 Java 有点陌生,但我学得很快。尽管如此,仍有许多方法让我无法理解。我正在编写一个 Java 程序,该程序将运行一堆文件并彻底测试它们以查看它们是否是有效的关卡包文件。感谢 Matt Olenik 和他的 GobFile 类(仅用于提取文件),我能够找到一个很好的策略来获取关卡包的重要部分及其各自的地图文件,以快速确定各种细节。 但是,在 37 个文件(其中 5 个不是关卡包)上对其进行测试,它在测试 35 个文件后崩溃。第 35 个文件是有效的关卡包。它给出的错误是:
线程“主”java.lang.OutOfMemoryError 中的异常:Java 堆空间
Iterator iter = itemList.keySet().iterator();
numJKLs = 0;
while (iter.hasNext()) {
String nextFile = (String) iter.next();
if (nextFile.startsWith("jkl\\")) {
System.out.println(((ItemInfo) itemList.get(nextFile)).length);
--> byte[] buffer = new byte[((ItemInfo) itemList.get(nextFile)).length];
gobRaf.seek(((ItemInfo) itemList.get(nextFile)).offset);
gobRaf.read(buffer, 0,
((ItemInfo) itemList.get(nextFile)).length);
String[] content = new String(buffer).toLowerCase().split(
"\n");
levels.add(numJKLs, new JKLFile(theFile, nextFile, content));
gametype = levels.get(numJKLs).getFileType();
progress.setProgText(nextFile);
buffer = null;
content = null;
numJKLs++;
}
}
箭头显示错误标记的位置。 'JKLFile' 类为这些重要部分读取content 数组,但应该(理论上)在完成后处理它。就像这里一样,我在JKLFile 中设置了content = null;,只是为了确保它消失了。如果您想知道它停止的地图文件有多大,那么它设法传递了一个 17 Mb 的地图文件,但这个只有 5 Mb。
如您所见,这些 JKLFile 对象保存在此对象 (GobFile.java) 中以方便以后访问,GobFile 对象保存在另一个类中以供以后访问,直到我更改目录(未实现然而)。但这些物品不应该塞满东西。只是文件名和各种详细信息的列表。
关于如何找出内存去向或哪些对象使用最多资源的任何建议?当我从列表中单击它们时,最好将详细信息保留在内存中,而不必再次加载文件(最多 2 秒)。
/爱德华
【问题讨论】:
-
您要将所有文件添加到
levels?你猜它有多大???? -
@HotLicks 我不会将整个内容添加到
levels。没错,我正在发送内容,但我希望它不会被保存。只需处理关键细节并保存 2 个整数和 2 个字符串(级别名称和文件名)。 -
在我看来,您正在将每个文件的内容添加到
levels--levels.add(numJKLs, new JKLFile(theFile, nextFile, content));。因此,您可以一次有效地将所有文件读取到存储中(仅以您读取它们的方式,它们占用的空间可能是原始文件的 5 倍)。 -
@HotLicks 好吧,我从整个关卡包中的特定文件中获取的详细信息位于文件中间,前面有未知数量的声明,后面有未知数量的东西.我尝试使用
.readLine(),但运行一些文件需要很长时间。这是迄今为止最快的策略。 -
那么你必须处理所有这些数据填满堆的后果。显然,
levels对象中的每个文件的每一行都有。
标签: java file memory out-of-memory