簡體   English   中英

使用掃描儀將大文件讀入內存,導致內存不足

[英]Out of memory using Scanner to read large file into memory

當我將大文件傳遞到掃描儀時,以下代碼塊將引發java.lang.OutOfMemoryError異常。 解決此問題的最佳方法是什么? 問題在陣列列表或掃描儀中嗎?

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

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

增加Java堆大小,例如

java -Xmx6g myprogram

會將堆大小設置為6 GB。 當然總會有一個限制。

主要問題是存儲在陣列列表上。 另外,嘗試使用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();

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()調用都會返回下一個標記,直到找到空白為止。 更改分隔符,增加內存大小或更改設計。

您的文件格式是什么?

無需將文件中的所有行加載到ArrayList ,而是在讀取記錄后立即對每個記錄執行所需的操作。 如果堆大小不夠大,則將整個文件加載到內存中會導致OOM問題。

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

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM