Java: невозможно создать новый собственный поток
У меня есть Java-приложение, которое размещено на веб-хостинге. Каждые несколько дней мое приложение закрывается:
[2011-03-09 15:52:14,501] ERROR http-12021-9
java.lang.OutOfMemoryError: unable to create new native thread
at java.lang.Thread.start0(Native Method)
at java.lang.Thread.start(Thread.java:597)
Хостинговая компания говорит, что это означает, что у моего приложения есть утечка памяти, но инструменты, которые я имею, показывают свободную память, все еще доступны. Поскольку ошибка всегда создает новый собственный поток, я думаю, что проблема заключается в ресурсах config/OS JVM.
Как я могу предотвратить эту ошибку?
6 ответов
Возможно, вы достигли ограничения на количество открытых файлов.
Я считаю, что каждый процесс / поток потребляет один или несколько файловых дескрипторов.
Например, когда это происходит для вашего пользователя, тогда будет работать команда оболочки "no", так как команды оболочки отключают процесс для выполнения (вы видите ошибки типа "-bash: fork: retry: Ресурс временно недоступен")
Я столкнулся с этой проблемой и обнаружил, что только текущий пользователь не смог порождать процессы... другие пользователи не пострадали.
To resolve, up your ulimit -n (max files open) setting... details follow.
You can see your user limits with the command:
ulimit -a
Up your max file limit with the following:
ulimit -n 65536
Вот что у меня сейчас есть:
$ 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) 256797
max locked memory (kbytes, -l) 64
max memory size (kbytes, -m) unlimited
open files (-n) 75000
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) 100000
virtual memory (kbytes, -v) unlimited
file locks (-x) unlimited
To see all the explicit limits for your system:
cat /etc/security/limits.conf
Please note: I'm using Oracle Linux 6.3 - results may differ slightly between distros.
Скорее всего, проблема с JVM в конце веб-сервера. Пожалуйста, проверьте следующую ссылку для некоторых деталей,
Это ответ всем, кто запускает java через systemd. (например, самостоятельно созданная служба Tomcat)
Я запускал свое Java-приложение на сервере через Tomcat. Я также создал служебный модуль в systemd для удобства, поэтому он запускается при загрузке сервера, и я также могу управлять им через systemd (илиservice tomcat restart
).
Но есть некоторые значения по умолчанию для модулей systemd и их максимально разрешенных задач (потоков). Для меня на моей машине было 195 Задач. Как только я изменил значение в сервисном блоке с помощьюTasksMax=1024
и перезагрузил его с systemctl daemon-reload
все заработало как положено.
Например, файл служебной единицы в /etc/systemd/system/tomcat.service
[Unit]
Description=Tomcat9
After=network.target
[Service]
Type=forking
User=tomcat9
Group=tomcat9
TasksMax=1048
Environment=CATALINA_PID=/opt/tomcat/tomcat9.pid
Environment=JAVA_HOME=/usr/lib/jvm/default-java
Environment=CATALINA_HOME=/opt/tomcat
Environment=CATALINA_BASE=/opt/tomcat
Environment="CATALINA_OPTS=-Xms2048m -Xmx28384m"
Environment="JAVA_OPTS=-Dfile.encoding=UTF-8 -Dnet.sf.ehcache.skipUpdateCheck=true -XX:+UseConcMarkSweepGC -XX:+CMSClassUnloadingEnabled -XX:+UseParNewGC"
ExecStart=/opt/tomcat/bin/startup.sh
ExecStop=/opt/tomcat/bin/shutdown.sh
[Install]
WantedBy=multi-user.target
Когда вы запускаете ваш процесс, JVM имеет ограниченный размер кучи (по умолчанию 128 МБ). У этого сервера может быть больше памяти, но у вашей JVM нет - вы использовали все это.
Вы можете изменить это с помощью -Xms
а также -Xmx
аргументы командной строки, но я бы предложил сначала найти утечку памяти:)
Вы занимались отслеживанием памяти? Запустите jconsole и наблюдайте или регистрируйте потребление памяти в течение 24 часов. Если он (в среднем) идет вверх, не возвращаясь вниз, значит, вам не хватает памяти и, возможно, недостаточно памяти для хранения сведений о новом потоке.
Это проблема с Linux для обработки №. Открытых файлов. Давайте следующим образом ulimit -n 65536 (любое число, которое вы можете дать)
Похоже, нить протекает. Потоки созданы, но потом где-то застряли. Периодически сбрасывайте потоки, чтобы увидеть, увеличивается ли количество выделенных потоков. Ищите любые спящие / висящие темы в свалке.
kill -QUIT jvm_pid