Puede usar un programa de muestra para averiguar el límite actual de subprocesos.
Si encuentra Exception in thread "main" java.lang.OutOfMemoryError: unable to create new native thread
, marque estos:
-
En pequeñas máquinas de memoria
Cada subproceso de Java consume su propia memoria de pila. El tamaño de pila predeterminado es 1024k (=1M). Puede reducir el tamaño de la pila como
java -Xss512k ...
. JVM no se puede iniciar si el tamaño de la pila es demasiado bajo.Y tenga cuidado con las configuraciones de memoria en montón:(inicial)
-Xms
y (máximo)-Xmx
. Cuanta más memoria se asigna al montón, menos memoria disponible para la pila. -
Límites del sistema
Algunos valores en
ulimit -a
puede afectar un límite de subprocesos.max memory size
- ilimitado en la mayoría de las máquinas de 64 bitsmax user processes
- Linux trata los hilos como procesosvirtual memory
- ilimitado en la mayoría de las máquinas de 64 bits. el uso de memoria virtual aumenta con la configuración -Xss (predeterminada 1024k)
Puede cambiar estos valores ejecutando (temporalmente)
ulimit
comando o edición (permanente)/etc/security/limits.conf
. -
sys.kernel.threads-max
Este valor es el número máximo de subprocesos global del sistema (incluidos los procesos que no son JVM). Marque
cat /proc/sys/kernel/threads-max
y aumente si es necesario.echo 999999 > /proc/sys/kernel/threads-max
o
sys.kernel.threads-max = 999999
en/etc/sysctl.conf
para cambiar permanentemente. -
sys.kernel.pid_max
Si
cat /proc/sys/kernel/pid_max
es similar al límite actual, aumente esto. Linux trata los hilos como procesos.echo 999999 > /proc/sys/kernel/pid_max
o
sys.kernel.pid_max = 999999
en/etc/sysctl.conf
para cambiar permanentemente.Y es posible que deba aumentar
sys.vm.max_map_count
, también. -
sys.vm.max_map_count
cat /proc/sys/vm/max_map_count
debe ser al menos (2 x número de hilos).Attempt to protect stack guard pages failed.
yOpenJDK 64-Bit Server VM warning: Attempt to deallocate stack guard pages failed.
JavaThread::create_stack_guard_pages() emite mensajes de error y llama a os::guard_memory(). En Linux, esta función es mprotect().echo 1999999 > /proc/sys/vm/max_map_count
o
sys.vm.max_map_count = 1999999
en/etc/sysctl.conf
para cambiar permanentemente.
Información adicional para sistemas linux modernos (systemd).
Hay muchos recursos sobre estos valores que pueden necesitar ajustes (la otra respuesta es una buena fuente para la mayoría de ellos); sin embargo, se impone un nuevo límite a través del límite systemd "TasksMax" que establece pids.max en cgroup.
Para las sesiones de inicio de sesión, el valor predeterminado de UserTasksMax es el 33 % del límite del kernel pids_max (normalmente 12 288) y se puede anular en /etc/systemd/logind.conf.
Para los servicios, el valor predeterminado de DefaultTasksMax es el 15 % del límite del kernel pids_max (normalmente 4915). Puede anularlo para el servicio configurando TasksMax en "systemctl edit" o actualizando DefaultTasksMax en /etc/systemd/system.conf
Me encontré con un problema similar en un programa de Python y lo siguiente funcionó para mí. Esto se basa en la respuesta anterior de maczniak y 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
También tuve que configurar DefaultTasksMax
en /etc/systemd/system.conf
(o /etc/systemd/user.conf
para servicios ejecutados por el usuario) a DefaultTasksMax=unlimited
.
Systemd también aplica un límite para los programas que se ejecutan desde un shell de inicio de sesión. Por defecto, son 4096 por usuario (se incrementará a 12288) y están configurados como UserTasksMax en la sección [Iniciar sesión] de /etc/systemd/logind.conf
.
Eso es de esta pregunta de StackExchange. Configurando mi UserTasksMax
a UserTasksMax=999999
funcionó para mí.