2016-11-28 231 views
0

我對BlueJ的Java堆空間有問題。 我已經寫了一個程序,它讀入一個字符串的.txt文件並遍歷字符串的所有字符並做一些事情(猜測這並不重要)。一些.txt文件非常大(約2億個)。 如果我嘗試用這些.txt執行程序,我得到這個「異常在線程」AWT-EventQueue-0「java.lang.OutOfMemoryError:Java堆空間」錯誤代碼。我將bluej.def中的bluej.windows.vm.args和bluej.windows.vm.args增加到8gb。它仍然不起作用。但我實際上猜測即使是一個2億字符的字符串也不會超過這個限制。 這是我的我在.TXTBlueJ的Java堆空間

try 
    { 
     FileReader reader = new FileReader(input.getText()); 
     BufferedReader bReader = new BufferedReader(reader); 
     String parcour = ""; 
     String line = bReader.readLine(); 
     while(line != null) 
     { 
      parcour += line; 
      line = bReader.readLine();    
     } 

input.getText()獲取文件路徑如何閱讀代碼。 我會很感激的答案。謝謝:) - Cyaena

+1

您正在將整個文件存儲在'parcour'變量中。這會吃掉很多的記憶。另外,在將數據附加到字符串 – ar34z

+0

時考慮使用'StringBuilder',但實際上String不應該佔用那麼多的內存,不是嗎?我必須使用StringBuilder有什麼優勢?我該如何粗略設置它? – Cyaena

+1

我不是解釋內存使用情況的正確人選,但存儲了200萬個。內存中的字符聽起來不太有希望。在循環中連接字符串時,「StringBuilder」更快。你想用這2億行做什麼?也許這可以幫助你:http://stackoverflow.com/questions/10202905/is-it-advisable-to-store-large-strings-in-memory-or-repeatedly-read-a-file有關內存使用情況的更多信息:http://www.javamex.com/tutorials/memory/string_memory_usage.shtml – ar34z

回答

0

在下面的說明中,只有數據的純內存在範圍內。所有額外的內存需求的結構被遺漏。這是更詳細的概述。

存儲器被在那些線

String parcour = ""; 
... 
String line = bReader.readLine(); 
... 
parcour += line; 

parcour += line吃掉編譯成類文件作爲

new StringBuilder().append(parcour).append(line).toString() 

假設parcour包含大小爲10 MB的字符串和line將大小的2 MB。然後在parcour += line;分配的內存將是(大約)需要

// creates a StringBuilder object of size 12 MB 
new StringBuilder().append(parcour).append(line) 

// the `.toString()` would generate a String object of size 12 MB 
new StringBuilder().append(parcour).append(line).toString() 

你的代碼之前,新創建的字符串被分配到parcour約34 MB。

parcour       = 10 MB 
the temporary StringBuilder object = 12 MB 
the String fromStringBuilder  = 12 MB 
------------------------------------------ 
total        34 MB 

一個小的演示片段,表明OutOfMemoryException比目前預期的要早得多。

OOMString.java

class OOMString { 
    public static void main(String[] args) throws Exception { 
     String parcour = ""; 
     char[] chars = new char[1_000]; 
     String line = new String(chars); 
     while(line != null) 
     { 
      System.out.println("length = " + parcour.length()); 
      parcour += line; 
     }   
    } 
} 

OOMStringBuilder.java

class OOMStringBuilder { 
    public static void main(String[] args) throws Exception { 
     StringBuilder parcour = new StringBuilder(); 
     char[] chars = new char[1_000]; 
     String line = new String(chars); 
     while(line != null) 
     { 
      System.out.println("length = " + parcour.length()); 
      parcour.append(line); 
     }   
    } 
} 

兩個片段做同樣的。他們在parcour中添加了1000個charcater字符串,直到OutOfMemoryException被引發。爲了加快速度,我們將堆大小限制爲10 MB。

的輸出java -Xmx10m OOMStringBuilder

length = 2052000 
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space 

java -Xmx10m OOMString

length = 1048000 
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space 

輸出當你執行的代碼,你會發現,OOMString需要更多的時間來失效(甚至在更短的長度)比OOMStringBuilder

您還需要記住單個字符是兩個字節長。如果您的文件包含100個ASCII字符,則它們在內存中佔用200個字節。

也許這個小小的演示可以爲你解釋一點點。

0

我也有BlueJ和堆空間錯誤以及一些問題。就我而言,打開終端會使整個應用程序崩潰。我懷疑這與生成大量輸出有關,與您的大型字符串類似。就我而言,我意外地創造了一個無處不在的循環,打破了終端窗口。我不得不刪除所有的屬性文件。現在BlueJ再次工作,不再發生OutOfMemoryErrors。 我希望這可能對其他情況也有幫助。