2014-05-19 4 views
1

Я использую парсер для определения 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 и 2,1 миллиардами элементов.

Итак, когда вы сталкиваетесь с java.lang.OutOfMemoryError: размер запрашиваемого массива превышает лимит VM, приложение под рукой пытается выделить массив, который может поддерживать ваш виртуальный компьютер Java.

Ошибка вызвана нативным кодом в JVM. Это происходит, прежде чем выделять память для массива, когда JVM выполняет проверку конкретной платформы: разрешена ли выделенная структура данных на этой платформе.

Эта ошибка встречается менее часто, чем вы могли бы изначально подумать. Причина этого заключается в том, что массивы Java индексируются int. Если вы помните, максимальный положительный int в java равен 2^31 - 1 = 2,147,483,647. И ограничения, зависящие от платформы, могут быть очень близки к этому числу - например, на моем 64-битном MB Pro на Java 1.7 я могу с радостью инициализировать массивы с до 2,147,483,645 или Integer.MAX_VALUE-2.

Увеличение длины массива на единицу, до Integer.MAX_VALUE-1 приводит к тому, что вызывается знакомый OutOfMemoryError.

Но предел, возможно, не в том, что на 32-разрядном Linux-сервере с OpenJDK 6 вы нажмете на «java.lang.OutOfMemoryError: размер запрашиваемого массива превышает лимит VM» уже при распределении массива с ~ 1,1 млрд элементов , Чтобы понять пределы вашей конкретной среды, запустите небольшой тест, чтобы узнать об этом.

Смежные вопросы