Puoi utilizzare un programma di esempio per scoprire il limite di thread corrente.
Se incontri Exception in thread "main" java.lang.OutOfMemoryError: unable to create new native thread
, controlla questi:
-
In piccole macchine di memoria
Ogni thread Java consuma la propria memoria stack. La dimensione predefinita dello stack è 1024k (=1M). Puoi ridurre la dimensione dello stack come
java -Xss512k ...
. JVM non può essere avviato se la dimensione dello stack è troppo bassa.E attenzione alle configurazioni della memoria dell'heap:(iniziale)
-Xms
e (massimo)-Xmx
. Maggiore è la memoria assegnata all'heap, minore sarà la memoria disponibile per lo stack. -
Limiti di sistema
Alcuni valori in
ulimit -a
può influenzare un limite di thread.max memory size
- illimitato sulla maggior parte delle macchine a 64 bitmax user processes
- linux tratta i thread come processivirtual memory
- illimitato sulla maggior parte delle macchine a 64 bit. l'utilizzo della memoria virtuale è aumentato dalla configurazione -Xss (predefinito 1024k)
Puoi modificare questi valori eseguendo (temporalmente)
ulimit
comando o modifica (permanente)/etc/security/limits.conf
. -
sys.kernel.threads-max
Questo valore è il numero massimo globale di thread di sistema (compresi i processi non JVM). Seleziona
cat /proc/sys/kernel/threads-max
, e aumenta se necessario.echo 999999 > /proc/sys/kernel/threads-max
o
sys.kernel.threads-max = 999999
in/etc/sysctl.conf
cambiare definitivamente. -
sys.kernel.pid_max
Se
cat /proc/sys/kernel/pid_max
è simile al limite di corrente, aumentalo. Linux tratta i thread come processi.echo 999999 > /proc/sys/kernel/pid_max
o
sys.kernel.pid_max = 999999
in/etc/sysctl.conf
da modificare in modo permanente.E potrebbe essere necessario aumentare
sys.vm.max_map_count
anche. -
sys.vm.max_map_count
cat /proc/sys/vm/max_map_count
dovrebbe essere almeno (2 x numero di thread).Attempt to protect stack guard pages failed.
eOpenJDK 64-Bit Server VM warning: Attempt to deallocate stack guard pages failed.
i messaggi di errore vengono emessi da JavaThread::create_stack_guard_pages() e chiama os::guard_memory(). In Linux, questa funzione è mprotect().echo 1999999 > /proc/sys/vm/max_map_count
o
sys.vm.max_map_count = 1999999
in/etc/sysctl.conf
da modificare in modo permanente.
Ulteriori informazioni per i moderni sistemi Linux (systemd).
Ci sono molte risorse su questo di valori che potrebbero richiedere modifiche (l'altra risposta è una buona fonte per la maggior parte di essi); tuttavia viene imposto un nuovo limite tramite il limite systemd "TasksMax" che imposta pids.max sul cgroup.
Per le sessioni di accesso, l'impostazione predefinita di UserTasksMax è il 33% del limite del kernel pids_max (in genere 12.288) e può essere ignorata in /etc/systemd/logind.conf.
Per i servizi, il valore predefinito di DefaultTasksMax è il 15% del limite del kernel pids_max (in genere 4.915). Puoi sovrascriverlo per il servizio impostando TasksMax in "systemctl edit" o aggiornando DefaultTasksMax in /etc/systemd/system.conf
Mi sono imbattuto in un problema simile in un programma Python e il seguente ha funzionato per me. Questo si basa sulla risposta di maczniak sopra e su 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
Ho anche dovuto impostare DefaultTasksMax
in /etc/systemd/system.conf
(o /etc/systemd/user.conf
per i servizi gestiti dall'utente) a DefaultTasksMax=unlimited
.
Systemd applica anche un limite per i programmi eseguiti da una login-shell. Questi valori predefiniti sono 4096 per utente (saranno aumentati a 12288) e sono configurati come UserTasksMax nella sezione [Login] di
/etc/systemd/logind.conf
.
Questo è da questa domanda di StackExchange. Impostazione del mio UserTasksMax
a UserTasksMax=999999
ha funzionato per me.