0

当我将大文件传递到扫描仪时,以下代码块会引发 java.lang.OutOfMemoryError 异常。解决此问题的最佳方法是什么?是阵列列表还是扫描仪的问题?

ArrayList rawData = new ArrayList();
Scanner scan = new Scanner(file);

while (scan.hasNext()) {
    String next = scan.next();
        rawData.add(next);
}
4

4 回答 4

3

增加java堆大小,例如

java -Xmx6g myprogram

将堆大小设置为 6 GB。当然,总会有限制的......

于 2013-09-08T22:32:26.090 回答
3

主要问题是存储在数组列表中。此外,尝试使用 bufferReader 并在 while 语句中进行处理,而不是尝试将其添加到数组列表中。这是一个简单的例子。

        File file = new File("C:\\custom_programs\\reminder_list.txt");
        BufferedReader br = new BufferedReader(new FileReader(file));
        String line;
        while ((line = br.readLine()) != null) {
            // do something with line.
            System.out.println(line);
        }
        br.close();
于 2013-09-08T22:45:58.580 回答
0

a 的默认分隔符Scanner是空格。

public Scanner(ReadableByteChannel source) { // Your File is converted to a ReadableByteChannel from another constructor 
    this(makeReadable(Objects.requireNonNull(source, "source")),
         WHITESPACE_PATTERN);
}

因此,如果您的文件包含许多空白字符,您将在

while (scan.hasNext()) {
    String next = scan.next();
    rawData.add(next);
}

将许多对象放入您的ArrayList但不是垃圾收集任何东西(即不释放内存)。

每次调用都next()返回下一个标记,直到找到空格。要么改变分隔符,增加你的内存大小,要么改变你的设计。

你的文件格式是什么?

于 2013-09-08T22:33:19.330 回答
0

与其将文件中的所有行加载到ArrayList中,不如在读取每条记录后立即执行您想要的操作。如果 heapsize 不够大,将整个文件加载到内存中会导致 OOM 问题。

Scanner scan = new Scanner(file);
while (scan.hasNext()) {
    String next = scan.next();
    //do what you want to do on next
}
于 2013-09-08T22:36:29.993 回答