2014-05-19 77 views
1

我正在使用jsoup解析器讀取HTML文件並創建提取數據的XML文件。我將在一個包含多個html文件(〜250k - 300k文件)的目錄中運行此代碼/腳本,其中一些文件很大。JSoup - Java OutOfMemoryError - 在大文件中使用jsoup解析器

我碰上了

java.lang.OutOfMemoryError: Requested array size exceeds VM limit" or Java heap space 

錯誤。我曾嘗試使用不同的-Xmx-Xms值運行虛擬機,但我一直在碰到同樣的錯誤。我附上了我的代碼片段。 我假設讀取大文件時發生錯誤。任何想法如何解決這個問題?

String target_dir_output = "/test/"; 
File dir = new File(target_dir); 
File[] files = dir.listFiles(); 
for (File f : files) { 
    if(f.isFile()) { 
     String fileName = f.getName(); 
     String testValue = null; 
     try { 
      Document doc = Jsoup.parse(f, "UTF-8", ""); 
      Elements metalinks = doc.select("meta[name=testValue]"); 
      testValue = metalinks.first().attr("content"); 
      String output = "<data>" + "\n"; 
      output += "<testValue>" + testValue + "</testValue>" ; 
      output += "</data>"; 
      FileOutputStream out = new FileOutputStream(fileName + ".xml"); 
      out.write(output.getBytes()); 
      out.close(); 
     } catch (IOException e) { 
      e.printStackTrace(); 
     } 
+0

文件的大小如何? – Whymarrh

+0

1360554953是最大文件之一的文件大小。大部分文件屬於這個類別。 – User

+0

您是否嘗試過運行'-Xms'和'-Xmx'? – Whymarrh

回答

4

Java已經限制了程序可以分配的最大數組大小。確切的限制是平臺特定的,但通常在1到21億個元素之間。

因此,當您面對java.lang.OutOfMemoryError:請求的數組大小超過VM限制時,應用程序正在嘗試分配一個大於Java虛擬機可以支持的數組。

錯誤是由JVM中的本地代碼拋出的。它在爲數組分配內存之前發生,當JVM執行特定於平臺的檢查時:在此平臺中分配的數據結構是否可尋址。

這個錯誤比您最初想象的要少。原因是基於Java數組通過int索引的事實。如果您記得,java中的最大正整數是2^31 - 1 = 2,147,483,647。特定於平臺的限制可以非常接近這個數字 - 例如在Java 1.7上的64位MB Pro上,我可以高興地初始化數組,最多2,147,483,645或Integer.MAX_VALUE-2元素。

將數組長度增加一個Integer.MAX_VALUE-1會導致引發熟悉的OutOfMemoryError。

但是這個限制可能不是那麼高 - 在使用OpenJDK 6的32位Linux上,當分配一個包含11億個元素的數組時,您將遇到「java.lang.OutOfMemoryError:請求的數組大小超過VM限制」 。要了解您的特定環境的限制,請運行一個小測試找出它。