Comment résoudre l'erreur Java" pool-1-thread-xxxx " java.lang.OutOfMemory
J'ai cherché dans les articles sur ce problème, mais je n'ai pas vu de situation similaire à la mienne.
Ma console java affiche le message d'erreur "pool-1-thread-xxxx" java.lang.OutOfMemory
comme l'image ci-dessous:
- Ligne rouge: utilisation du processeur
- Ligne verte: Utilisation de la mémoire
J'ai augmenté la RAM de 6G
à 10G
et défini -Xms=8G -Xmx=8G -Xmn=3G
dans le fichier *.bat
avant de démarrer le programme. Je continue également à regarder le moniteur de performance mais la mémoire est toujours autour de 20%. Je n'ai aucune idée de comment cela pourrait-il arriver. Une idée?
Voici mon run.bat
code.
@echo off
javapro @java -Xoptimize -Xms8G -Xmx8G -Xmn3G -Xss1024k -XX:+UseConcMarkSweepGC -cp javaPro.exe;
cls
run.bat
- SYSTÈME d'exploitation: Windows server 2012 R2
- Java version : jre1.8.0_171
- RAM: 10G
- PROCESSEUR: 2,5 GHz Intel Xeon(R)(Hyper Filetée)
2 answers
Le message d'erreur java.lang.OutOfMemoryError: unable to create new native thread
signifie que
La JVM demande un nouveau thread du système d'exploitation et du système d'exploitation sous-jacent impossible d'allouer un nouveau thread.
Voir OOM explications et votre cas spécifique expliqué.
Vous ne verrez donc pas une utilisation élevée de la mémoire dans le graphique, car la taille du tas n'est pas proche de sa limite.
Vous devez vérifier votre code d'application et inspecter les utilisations du pool de threads. C'est difficile de dire quoi que ce soit sans le code source, mais il peut y avoir peu de suggestions:
- Si vous utilisez
CachedThreadPoolExecutor
, les tâches soumises peuvent ne pas être assez rapides, de sorte que votre application ne peut pas traiter toutes les tâches soumises. - Vous pouvez utiliser
FixedThreadPoolExecutor
avec la capacité maximale (Integer.MAX_VALUE
), dans ce cas, vous devez limiter la capacité du pool et sa taille de file d'attente. Ainsi, le pool mange tous les threads disponibles etOOM
se produit.
Généralement, vous devez toujours contrôler la configuration de votre pool de threads et être sûr qu'elle ne monopolisera pas tout les ressources du système.
Pense que j'ai trouvé une approche raison / solution possible:
On peut vérifier la limite souple pour les processus avec ulimit -a
:
$ cat /proc/22666/limits | grep processes
Max processes 1024 62265 processes
$ ulimit -a | grep processes
max user processes
Afin de changer ces valeurs:
$ ulimit -Su 2000
$ ulimit -a | grep processes
max user processes (-u) 2000
$ cat /proc/22666/limits | grep processes
Max processes 2000
On peut également ajuster la configuration par défaut:
-
Modifier les limites.fichier conf avec les éléments suivants:
sudo nano /etc/security/limits.conf
ou de regarder à l'intérieur de/etc/security/limit.d/
.Ajoutez ce qui suit pour l'utilisateur qui exécute
java
.
Les Limites.conf
#<domain> <type> <item> <value>
# adjust these values as needed:
someuser soft nofile 4096
someuser hard nofile 8192
Puis modifiez le fichier common-session
avec ce qui suit:
sudo nano /etc/pam.d/common-session
Ajouter la ligne suivante:
Session commune
session required pam_limits.so
Et redémarrez java.
- voir aussi le ThreadPoolExecutor...
- et la configuration ThreadPoolExecutor.
Pour un serveur Windows 2012, ce serait à peu près la même chose.
- voir Pousser le Limites de Windows sur le blog Tech Net.