Как увеличить максимальное количество потоков JVM (Linux 64 бит)

Я не могу создать более 32 тыс. Java-потоков в Linux-машине с 15 ГБ памяти.

Ответы

Ответ 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 работала для меня.