Come risolvere l'errore Java "pool-1-thread-xxxx" java.lang.Fuori dalla memoria
Ho cercato i post su questo problema, ma non ho visto una situazione simile alla mia.
La mia console java mostra il messaggio di errore "pool-1-thread-xxxx" java.lang.OutOfMemory
come nell'immagine qui sotto:
- Linea rossa: utilizzo della CPU
- Linea verde: utilizzo della memoria
Ho aumentato la RAM da 6G
a 10G
e impostato -Xms=8G -Xmx=8G -Xmn=3G
nel file *.bat
prima di avviare il programma. Continuo anche a guardare il monitor delle prestazioni ma la memoria è sempre intorno al 20%. Non ho idea di come sia potuto succedere. Qualche idea?
Ecco il mio codice run.bat
.
@echo off
javapro @java -Xoptimize -Xms8G -Xmx8G -Xmn3G -Xss1024k -XX:+UseConcMarkSweepGC -cp javaPro.exe;
cls
run.bat
- Il sistema operativo: windows server 2012 R2
- Versione Java : jre1.8.0_171
- RAM: 10G
- CPU: 2.5 GHz Intel Xeon(R) (Hyper Threaded)
2 answers
Il messaggio di errore java.lang.OutOfMemoryError: unable to create new native thread
indica che
La JVM sta chiedendo un nuovo thread dal sistema operativo e dal sistema operativo sottostante impossibile allocare più un nuovo thread.
Vedi Spiegazioni OOMe il tuo caso specifico spiegato.
Quindi non vedrai un elevato utilizzo della memoria nel grafico, perché la dimensione dell'heap non è vicina al suo limite.
Devi controllare il codice dell'applicazione e ispezionare gli usi del pool di thread lì. È difficile dire qualcosa senza il codice sorgente, ma ci possono essere pochi suggerimenti:
- Se si utilizza
CachedThreadPoolExecutor
, le attività inviate potrebbero non essere abbastanza veloci, pertanto l'app non è in grado di elaborare tutte le attività inviate. - È possibile utilizzare
FixedThreadPoolExecutor
con la capacità massima (Integer.MAX_VALUE
), in tal caso è necessario limitare la capacità del pool e la sua dimensione della coda. Quindi il pool mangia tutti i thread disponibili eOOM
accade.
In generale, si dovrebbe sempre controllare la configurazione del pool di thread ed essere sicuri che non sarà hog tutto risorse di sistema.
Penso di aver trovato un possibile approccio alla ragione / soluzione:
Si può verificare il limite morbido per i processi con ulimit -a
:
$ cat /proc/22666/limits | grep processes
Max processes 1024 62265 processes
$ ulimit -a | grep processes
max user processes
Per modificare questi valori:
$ ulimit -Su 2000
$ ulimit -a | grep processes
max user processes (-u) 2000
$ cat /proc/22666/limits | grep processes
Max processes 2000
Si può anche regolare la configurazione predefinita:
-
Modificare i limiti .conf file con il seguente:
sudo nano /etc/security/limits.conf
o guarda dentro/etc/security/limit.d/
.Aggiungere quanto segue per l'utente che esegue
java
.
Limiti.conf
#<domain> <type> <item> <value>
# adjust these values as needed:
someuser soft nofile 4096
someuser hard nofile 8192
Quindi modificare il file common-session
con il seguente:
sudo nano /etc/pam.d/common-session
Aggiungere la seguente riga:
Sessione comune
session required pam_limits.so
E riavviare java.
- vedere anche il ThreadPoolExecutor...
- e la configurazione ThreadPoolExecutor .
Per un server Windows 2012, questo sarebbe circa lo stesso.
- vedere Spingendo il Limiti di Windows sul Blog Tech Net.