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

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

2 ответа

Решение

Вы можете использовать пример программы, чтобы узнать текущий предел потоков.

Если вы столкнулись Exception in thread "main" java.lang.OutOfMemoryError: unable to create new native threadпроверьте это:

  1. В маленьких машинах памяти

    Каждый поток Java потребляет свою собственную память стека. Размер стека по умолчанию составляет 1024 КБ (= 1 МБ). Вы можете уменьшить размер стека, как java -Xss512k ..., JVM не может быть запущена, если размер стека слишком мал.

    И остерегайтесь конфигураций кучи памяти: (начальная) -Xms и (максимум) -Xmx, Чем больше памяти выделено для кучи, тем меньше доступно памяти для стека.

  2. Системные ограничения

    Некоторые значения в ulimit -a может повлиять на ограничение потока.

    • max memory size - без ограничений на большинстве 64-битных машин
    • max user processes - Linux рассматривает потоки как процессы
    • virtual memory - Неограниченный на большинстве 64-битных машин. Использование виртуальной памяти увеличивается за счет конфигурации -Xss (по умолчанию 1024k)

    Вы можете изменить эти значения путем (временного) запуска ulimit команда или (постоянное) редактирование /etc/security/limits.conf,

  3. 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 постоянно меняться.

  4. 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, тоже.

  5. 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 работал у меня.

Другие вопросы по тегам