Как исправить ошибку «Размер запрашиваемого массива превышает ограничение виртуальной машины» в Java? - PullRequest
17 голосов
/ 31 марта 2011

Есть ли опция журнала, которая может позволить tomcat регистрировать неверный запрос, вместо этого просто выдавая это?

SEVERE: java.lang.OutOfMemoryError: Размер запрашиваемого массива превышает ограничение виртуальной машины

(Пытался уровень журнала до ПОЛНОГО, но только захватить выше)

Этой информации недостаточно для дальнейшей отладки
В качестве альтернативы, если это можно исправить, выделив больше памяти, настроив следующее?

-Xms1024M -Xmx4096M -XX: MaxPermSize = 256M

Обновление

-Xms6G -Xmx6G -XX: MaxPermSize = 1G -XX: PermSize = 512M

(кажется, выше работает лучше, продолжайте мониторинг)

Ответы [ 6 ]

13 голосов
/ 31 марта 2011

Я подозреваю, что вы можете использовать сортировки для большого индекса. Это то, что я точно знаю, может потребовать большой размер массива с Lucene. В любом случае, вы можете попробовать использовать 64-битную JVM со следующими параметрами:

-Xmx6G -XX:MaxPermSize=128M -XX:+UseCompressedOops

Последняя опция уменьшит 64-битные указатели памяти до 32-битных (до тех пор, пока куча не станет меньше 32 ГБ). Как правило, это сокращает накладные расходы памяти примерно на 40%, поэтому может помочь значительно увеличить объем памяти.

Обновление: Скорее всего, вам не нужен такой большой размер постоянного поколения, конечно, не 1G. Вероятно, у вас все в порядке с 128M, и вы получите конкретную ошибку, если перейдете на Java 6. Поскольку на вашем сервере вы ограничены 8G, вы можете сойти с 7G за кучу с меньшей разрешающей способностью. поколения. Будьте осторожны, не заходите в swap, это может серьезно замедлить работу Java.

Я заметил, что вы не упомянули -XX:+UseCompressedOops в своем обновлении. Это может иметь огромное значение, если вы еще не пробовали. Возможно, вам удастся выжать немного больше места, уменьшив размер eden, чтобы предоставить заемному поколению больше места. Кроме того, я думаю, вам просто понадобится больше памяти или меньше полей сортировки.

5 голосов
/ 17 апреля 2011

Если вы хотите узнать, что вызывает OutOfMemory, вы можете добавить

-XX:+HeapDumpOnOutOfMemoryError 

на ваш выбор Java.

В следующий раз, когда вы выйдете из памяти, вы получите файл дампа кучи, который можно проанализировать с помощью «jhat», который находится внутри jdk / lib. Jhat покажет вам, какие объекты существуют в вашей куче и сколько памяти они потребляют.

4 голосов
/ 09 июня 2017

Вы получите это исключение, потому что вы пытаетесь создать массив, который больше максимального непрерывного блока памяти в куче ваших виртуальных машин Java.

https://plumbr.eu/outofmemoryerror/requested-array-size-exceeds-vm-limit

Что такое решение?

java.lang.OutOfMemoryError: Запрашиваемый размер массива превышает ограничение виртуальной машины может появиться в результате одной из следующих ситуаций:

Ваши массивы становятся слишком большими и в конечном итоге имеют размер между пределом платформы и Integer.MAX_INT

Вы сознательно пытаетесь выделить массивы, превышающие 2 ^ 31-1 элементов, чтобы поэкспериментировать с ограничениями.

В первом случае проверьте базу кода, чтобы увидеть, действительно ли вам нужны такие большие массивы. Может быть, вы могли бы уменьшить размер массивов и покончить с этим. Или разделите массив на более мелкие куски и загрузите данные, с которыми вам нужно работать, в пакетах, соответствующих вашему ограничению платформы.

Во втором случае - помните, что массивы Java индексируются с помощью int. Таким образом, вы не можете выходить за пределы 2 ^ 31-1 элементов в своих массивах при использовании стандартных структур данных на платформе. Фактически, в этом случае вы уже заблокированы компилятором, который объявляет «ошибка: слишком большое целое число» во время компиляции. Но если вы действительно работаете с действительно большими наборами данных, вам нужно пересмотреть свои варианты. Вы можете загружать данные, с которыми вам нужно работать, небольшими партиями и при этом использовать стандартные инструменты Java, или вы можете выйти за рамки стандартных утилит. Один из способов добиться этого - заглянуть в класс sun.misc.Unsafe. Это позволяет вам выделять память напрямую, как это было бы в C.

0 голосов
/ 14 декабря 2011

Обновление solr до более новой версии, похоже, решает эту проблему, вероятно, более новая версия имеет лучшее управление кучей памяти.

0 голосов
/ 19 апреля 2011

Недостаточно памяти!Посмотрите, существует ли массив вне границ, или зациклите системные ресурсы!


  1. java.lang.OutOfMemoryError: пространство кучи Java В JVM, если 98%времени доступно для размера кучи GC и менее чем на 2% времени для выдачи этой информации об исключении.Настройка кучи JVM - это Java-программа, в которой пространство памяти JVM можно использовать для развертывания настроек.JVM при запуске автоматически устанавливает значение размера кучи, начальное пространство (то есть -Xms) является физической памятью 1/64, максимальное пространство (-Xmx) является физической памятью 1/4. JVM может использоваться для обеспеченияМожно установить Xmn-Xms-Xmx и другие параметры.

  2. Запрошенный размер массива превышает ограничение виртуальной машины: это связано с тем, что применение размера массива превышает размер пространства кучи, например256M пространства кучи в массиве для подачи заявки на 512M

0 голосов
/ 14 апреля 2011

Я использую это в catalina.sh

JAVA_OPTS="-Dsolr.solr.home=/etc/tomcat6/solr -Djava.awt.headless=true -server -XX:NewSize=256m -XX:MaxNewSize=256m -XX:PermSize=256m -XX:MaxPermSize=256m -XX:+DisableExplicitGC"

У меня никогда не было проблем с памятью на Tomcat / solr с 30M небольшими документами.У меня были проблемы с клиентом индексации solrJ.Мне пришлось использовать -Xms8G -Xmx8G для Java-клиента и добавлять документы порциями по 250 тыс. Документов.

...