Я не могу создать более 32 тыс. Java-потоков в Linux-машине с 15 ГБ памяти.
Как увеличить максимальное количество потоков JVM (Linux 64 бит)
Ответ 1
Вы можете использовать программу-образец, чтобы узнать текущий предел потоков.
Если вы столкнулись с Exception in thread "main" java.lang.OutOfMemoryError: unable to create new native thread
, проверьте следующее:
-
В небольших машинах памяти
Каждый поток Java потребляет собственную стек памяти. Размер стека по умолчанию - 1024k (= 1M). Вы можете уменьшить размер стека, например
java -Xss512k ...
. JVM не может быть запущен, если размер стека слишком низок.И будьте осторожны при конфигурировании памяти кучи: (начальная)
-Xms
и (максимальная)-Xmx
. Чем больше памяти выделено для кучи, тем меньше доступной памяти для стека. -
Системные ограничения
Некоторые значения в
ulimit -a
могут влиять на ограничение потока.-
max memory size
- неограниченный на большинстве 64-битных машин -
max user processes
- linux обрабатывает потоки как процессы -
virtual memory
- неограниченно на большинстве 64-битных машин. использование виртуальной памяти увеличивается с помощью конфигурации -Xss (по умолчанию 1024k)
Вы можете изменить эти значения на (временное) выполнение команды
ulimit
или (постоянное) редактирование/etc/security/limits.conf
. -
-
sys.kernel.threads-max
Это значение является системно-глобальным (включая процессы, отличные от JVM), максимальное количество потоков. Проверьте
cat /proc/sys/kernel/threads-max
и при необходимости увеличьте.echo 999999 > /proc/sys/kernel/threads-max
илиsys.kernel.threads-max = 999999
в/etc/sysctl.conf
для постоянного изменения. -
sys.kernel.pid_max
Если
cat /proc/sys/kernel/pid_max
аналогично пределу тока, увеличьте это. Linux обрабатывает потоки как процессы.echo 999999 > /proc/sys/kernel/pid_max
илиsys.kernel.pid_max = 999999
в/etc/sysctl.conf
для постоянного изменения.И вам может потребоваться также увеличить
sys.vm.max_map_count
. -
sys.vm.max_map_count
cat /proc/sys/vm/max_map_count
должно быть не менее (2 x потока).Attempt to protect stack guard pages failed.
иOpenJDK 64-Bit Server VM warning: Attempt to deallocate stack guard pages failed.
сообщения об ошибках испускаются JavaThread:: create_stack_guard_pages(), и он вызывает os:: guard_memory(). В Linux эта функция - mprotect().echo 1999999 > /proc/sys/vm/max_map_count
илиsys.vm.max_map_count = 1999999
в/etc/sysctl.conf
для постоянного изменения.
Ответ 2
Дополнительная информация для современных (системных) Linux-систем.
Существует много ресурсов для таких значений, которые могут нуждаться в настройке (другой ответ является хорошим источником для большинства из них); однако новый предел накладывается посредством предела systemd "TasksMax", который устанавливает pids.max в группе.
Для сеансов входа значение UserTasksMax по умолчанию составляет 33% от предела ядра pids_max (обычно 12,288) и может быть переопределено в /etc/Systemd/logind.conf.
Для служб DefaultTasksMax значение по умолчанию составляет 15% от предела ядра pids_max (обычно 4 915). Вы можете переопределить его для службы, установив TasksMax в "systemctl edit" или обновив DefaultTasksMax в/etc/systemd/system.conf
Ответ 3
Я столкнулся с подобной проблемой в программе на Python, и мне помогло следующее. Это основано на ответе maczniak выше и https://superuser.com/info/1219960/cannot-edit-proc-sys-kernel-threads-max.
echo kernel.threads-max = 1073741823 >> /etc/sysctl.conf && echo 1073741823 > /proc/sys/kernel/threads-max
echo kernel.pid_max = 999999 >> /etc/sysctl.conf && echo 999999 > /proc/sys/kernel/pid_max
echo vm.max_map_count = 2147483646 >> /etc/sysctl.conf && echo 2147483646 > /proc/sys/vm/max_map_count
echo vm.overcommit_memory = 1 >> /etc/sysctl.conf && echo 1 > /proc/sys/vm/overcommit_memory
echo fs.inotify.max_user_instances = 256 >> /etc/sysctl.conf && echo 256 > /proc/sys/fs/inotify/max_user_instances
sysctl -p
Мне также пришлось установить DefaultTasksMax
в /etc/systemd/system.conf
(или /etc/systemd/user.conf
для пользовательских служб) в DefaultTasksMax=unlimited
.
Systemd также применяет ограничение для программ, запускаемых из оболочки входа в систему. По умолчанию это значение равно 4096 на пользователя (будет увеличено до 12288) и настроено как UserTasksMax в разделе [Login] в
/etc/systemd/logind.conf
.
Это из этого вопроса StackExchange. Установка моего UserTasksMax
на UserTasksMax=999999
работала для меня.