Как увеличить максимальное количество потоков JVM (Linux 64bit)
Я не могу создать более 32 тыс. Java-потоков на компьютере Linux с 15G памяти.
2 ответа
Вы можете использовать пример программы, чтобы узнать текущий предел потоков.
Если вы столкнулись Exception in thread "main" java.lang.OutOfMemoryError: unable to create new native thread
проверьте это:
В маленьких машинах памяти
Каждый поток Java потребляет свою собственную память стека. Размер стека по умолчанию составляет 1024 КБ (= 1 МБ). Вы можете уменьшить размер стека, как
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
постоянно меняться.
Дополнительная информация для современных (systemd) систем Linux.
Есть много ресурсов об этом значения, которые могут потребоваться настроить (другой ответ является хорошим источником для большинства из них); однако новый предел налагается через ограничение systemd "TasksMax", которое устанавливает pids.max для cgroup.
Для сеансов входа в систему значение UserTasksMax по умолчанию составляет 33% от ограничения ядра pids_max (обычно 12 288) и может быть переопределено в /etc/systemd/logind.conf.
Для сервисов DefaultTasksMax по умолчанию составляет 15% от ограничения ядра pids_max (обычно 4915). Вы можете переопределить его для службы, установив TasksMax в "systemctl edit" или обновив DefaultTasksMax в /etc/systemd/system.conf
Я столкнулся с аналогичной проблемой в программе Python, и у меня сработало следующее. Это основано на ответе Maczniak выше и https://superuser.com/questions/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 в разделе [Вход] в
/etc/systemd/logind.conf
.
Это из этого вопроса StackExchange. Установка моегоUserTasksMax
к UserTasksMax=999999
работал у меня.