Как исправить ошибку "запрошенный размер массива превышает предел VM" в Java?

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

тяжелый: java.ленг.OutOfMemoryError: запрошенный размер массива превышает VM limit

(пробовал уровень журнала до полного, но только захватить выше)

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

-Xms1024M -Xmx4096M -Начала XX:MaxPermSize=256МБ

обновление

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

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

6 ответов


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

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

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

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

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


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

-XX:+HeapDumpOnOutOfMemoryError 

для ваших Java opts.

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


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

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

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

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

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

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

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

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


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


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

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


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


Я использую это в 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"

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