使用Scanner将大文件读入内存时内存不足

时间:2013-09-08 22:29:31

标签: java arraylist heap java.util.scanner

以下代码块在将大文件传递到扫描程序时抛出了java.lang.OutOfMemoryError异常。解决这个问题的最佳方法是什么?问题在于arraylist还是扫描仪?

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

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

4 个答案:

答案 0 :(得分:3)

增加java堆大小,例如

java -Xmx6g myprogram

将堆大小设置为6千兆字节。当然总有一个限制......

答案 1 :(得分:3)

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

        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();

答案 2 :(得分:0)

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()都会返回下一个标记,直到找到空格。更改分隔符,增加内存大小或更改设计。

您的文件格式是什么?

答案 3 :(得分:0)

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

Scanner scan = new Scanner(file);
while (scan.hasNext()) {
    String next = scan.next();
    //do what you want to do on next
}