Мы получаем "java.lang.OutOfMemoryError : unable to create new native Thread
"виртуальную машину 8 ГБ RAM после 32k потоков (ps -eLF | grep -c java)
Однако "top" and "free -m" shows 50% free memory available
. JDk - 64-битный и пробовал как с HotSpot, так и с JRockit. Сервер имеет Linux 2.6.18
Мы также пробовали OS stack size (ulimit -s)
настраивать и ограничивать максимальный процесс (ulimit -u), увеличивать limit.conf, но все тщетно.
Также мы испробовали почти все возможные комбинации размеров кучи, оставив их низким, высоким и т. Д.
Скрипт, который мы используем для запуска приложения,
/opt/jrockit-jdk1.6/bin/java -Xms512m -Xmx512m -Xss128k -jar JavaNatSimulator.jar /opt/tools/jnatclients/natSimulator.properties
Спасибо за ответ.
Мы пробовали редактировать /etc/security/limits.conf и ulimit, но все равно
[root@jboss02 ~]# ulimit -a
core file size (blocks, -c) 0
data seg size (kbytes, -d) unlimited
scheduling priority (-e) 0
file size (blocks, -f) unlimited
pending signals (-i) 72192
max locked memory (kbytes, -l) 32
max memory size (kbytes, -m) unlimited
open files (-n) 65535
pipe size (512 bytes, -p) 8
POSIX message queues (bytes, -q) 819200
real-time priority (-r) 0
stack size (kbytes, -s) 10240
cpu time (seconds, -t) unlimited
max user processes (-u) 72192
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
java
out-of-memory
Дипак Тевани
источник
источник
ExecutorService
Вместо этого используйте пул потоков ( ).Ответы:
Это не проблема памяти, хотя название исключения настоятельно предполагает это, а проблема с ресурсами операционной системы. У вас заканчиваются собственные потоки, т.е. сколько потоков операционная система позволит использовать вашей JVM.
Это редкая проблема, потому что вам редко нужно такое количество. У вас много безусловных потоков, порождаемых там, где потоки должны, но не завершаться?
Вы можете подумать о том, чтобы переписать использование Callable / Runnables под управлением Executor, если это вообще возможно. Существует множество стандартных исполнителей с различным поведением, которым ваш код может легко управлять.
(Есть много причин, по которым количество потоков ограничено, но они различаются от операционной системы к операционной системе)
источник
Я столкнулся с той же проблемой во время нагрузочного теста, причина в том, что JVM не может создать новый поток Java дальше. Ниже приведен исходный код JVM
В моем случае Jboss создает слишком много потоков для обслуживания запроса, но все потоки заблокированы. Из-за этого JVM исчерпывается потоками, а также памятью (каждый поток хранит память, которая не освобождается, потому что каждый поток заблокирован).
Проанализировав дампы потоков Java, мы обнаружили, что около 61 тыс. Потоков заблокировано одним из наших методов, что и вызывает эту проблему. Ниже представлена часть дампа потока
источник
Вероятно, ваша ОС не позволяет количество потоков, которые вы пытаетесь создать, или вы достигли некоторого ограничения в JVM. Особенно, если это такое круглое число, как 32к, очень вероятно, что виноват тот или иной лимит.
Вы уверены, что вам действительно нужно 32k потоков? Большинство современных языков имеют некоторую поддержку для пулов многоразовых потоков - я уверен, что в Java тоже что-то есть (например
ExecutorService
, как сказал пользователь Джеспер). Возможно, вы могли бы запросить потоки из такого пула вместо того, чтобы вручную создавать новые.источник
Я бы порекомендовал также взглянуть на размер стека потоков и посмотреть, сможете ли вы создать больше потоков. Размер стека потоков по умолчанию для JRockit 1.5 / 1.6 составляет 1 МБ для 64-разрядной виртуальной машины в ОС Linux. 32K потоков потребует значительного количества физической и виртуальной памяти для выполнения этого требования.
Попробуйте уменьшить размер стека до 512 КБ в качестве отправной точки и посмотрите, поможет ли это создать больше потоков для вашего приложения. Я также рекомендую изучить горизонтальное масштабирование, например, разделение обработки вашего приложения на большее количество физических или виртуальных машин.
При использовании 64-разрядной виртуальной машины истинный предел будет зависеть от доступности физической и виртуальной памяти ОС и параметров настройки ОС, таких как ulimitc. Я также рекомендую следующую статью в качестве ссылки:
OutOfMemoryError: невозможно создать новый собственный поток - проблема раскрыта
источник
Если jvm запускается через systemd, в некоторых ОС Linux может быть ограничение maxTasks на процесс (задачи фактически означают потоки).
Вы можете проверить это, запустив «статус службы» и проверив, есть ли ограничение maxTasks. Если есть, вы можете удалить его, отредактировав /etc/systemd/system.conf, добавив конфиг: DefaultTasksMax = infinity
источник
У меня была такая же проблема из-за призрачных процессов, которые не отображались при использовании top в bash. Это не позволяло JVM создавать больше потоков.
Для меня это разрешилось при перечислении всех java-процессов с jps (просто выполните
jps
в своей оболочке) и уничтожении их отдельно с помощью командыkill -9 pid
bash для каждого призрачного процесса.Это может помочь в некоторых сценариях.
источник
У вас есть шанс столкнуться с
java.lang.OutOfMemoryError: Unable to create new native thread
проблемой всякий раз, когда JVM запрашивает у ОС новый поток. Всякий раз, когда базовая ОС не может выделить новый собственный поток, будет выброшена эта ошибка OutOfMemoryError. Точный предел для собственных потоков очень зависит от платформы, поэтому рекомендуется выяснить эти ограничения, выполнив тест, аналогичный приведенному ниже примеру ссылки. Но в целом возникновение ситуацииjava.lang.OutOfMemoryError: Unable to create new native thread
проходит следующие фазы:Ссылка: https://plumbr.eu/outofmemoryerror/unable-to-create-new-native-thread
источник
Чтобы узнать, какие процессы создают потоки, попробуйте:
Обычно я перенаправляю вывод в файл и анализирую файл в автономном режиме (количество потоков для каждого процесса соответствует ожиданиям или нет)
источник
Если ваша работа не выполняется из-за OutOfMemmory на узлах, вы можете настроить количество максимальных карт и редукторов, и JVM выберет для каждого. mapred.child.java.opts (значение по умолчанию - 200Xmx) обычно необходимо увеличивать в зависимости от оборудования ваших узлов данных.
Эта ссылка может быть полезной ... пожалуйста, проверьте
источник
у вашей конфигурации JBoss есть некоторые проблемы, /opt/jrockit-jdk1.6/bin/java -Xms512m -Xmx512m Xms и Xmx ограничивают использование памяти JBoss до настроенного значения, поэтому из 8 ГБ у вас сервер использует только 512 МБ + немного лишнего для его собственных целей, увеличьте это число, не забудьте оставить немного свободного для ОС и других вещей, работающих там, и, возможно, вы запустите его, несмотря на сомнительный код. Было бы неплохо исправить код, если сможете.
источник
Эта ошибка может появиться по следующим двум причинам:
В памяти нет места для размещения новых потоков.
Количество потоков превышает предел операционной системы.
Я сомневаюсь, что количество потоков превысило лимит для java-процесса
Так что, возможно, проблема в памяти.
Возможное решение - уменьшить размер кучи или увеличить общий размер оперативной памяти.
источник
У меня была такая же проблема, и оказалось, что это неправильное использование Java API. Я инициализировал компоновщик в методе пакетной обработки, который не должен был инициализироваться более одного раза.
В основном я делал что-то вроде:
когда я должен был это сделать:
источник
Прежде всего, я бы не стал винить в этом ОС / ВМ ... скорее разработчика, написавшего код, который создает ооочень много потоков . По сути, где-то в вашем коде (или у стороннего разработчика) множество потоков создается бесконтрольно .
Внимательно просмотрите трассировку стека / код и контролируйте количество создаваемых потоков. Обычно вашему приложению не требуется большое количество потоков, иначе это уже другая проблема.
источник