web-dev-qa-db-fra.com

Comment augmenter le nombre maximal de threads JVM (Linux 64 bits)

Je ne peux pas créer plus de 32k Java sur une machine Linux avec une mémoire 15G.

15
maczniak

Vous pouvez utiliser un exemple de programme pour connaître la limite actuelle des threads.

Si vous rencontrez Exception in thread "main" Java.lang.OutOfMemoryError: unable to create new native thread, vérifiez-les:

  1. Dans les petites machines à mémoire

    Chaque Java consomme sa propre mémoire de pile. La taille de pile par défaut est 1024k (= 1M). Vous pouvez réduire la taille de pile comme Java -Xss512k .... La machine virtuelle Java ne peut pas être démarrée si la taille de la pile est trop faible.

    Et méfiez-vous des configurations de mémoire de tas: (initial) -Xms et (maximum) -Xmx. Plus la mémoire est allouée au tas, moins la mémoire disponible pour la pile.

  2. Limites du système

    Quelques valeurs dans ulimit -a peut affecter une limite de threads.

    • max memory size - illimité sur la plupart des machines 64 bits
    • max user processes - Linux traite les threads comme des processus
    • virtual memory - illimité sur la plupart des machines 64 bits. l'utilisation de la mémoire virtuelle est augmentée par la configuration -Xss (1024 k par défaut)

    Vous pouvez modifier ces valeurs en exécutant (temporairement) la commande ulimit ou en modifiant (en permanence) /etc/security/limits.conf.

  3. sys.kernel.threads-max

    Cette valeur est le nombre maximal de threads global du système (y compris les processus non JVM). Vérifier cat /proc/sys/kernel/threads-max, et augmentez si nécessaire.

    echo 999999 > /proc/sys/kernel/threads-max
    ou
    sys.kernel.threads-max = 999999 dans /etc/sysctl.conf pour changer définitivement.

  4. sys.kernel.pid_max

    Si cat /proc/sys/kernel/pid_max est similaire à la limite actuelle, augmentez-la. Linux traite les threads comme des processus.

    echo 999999 > /proc/sys/kernel/pid_max
    ou
    sys.kernel.pid_max = 999999 dans /etc/sysctl.conf pour changer définitivement.

    Et vous devrez peut-être augmenter sys.vm.max_map_count, aussi.

  5. sys.vm.max_map_count

    cat /proc/sys/vm/max_map_count doit être au moins (2 x nombre de threads).

    Attempt to protect stack guard pages failed. et OpenJDK 64-Bit Server VM warning: Attempt to deallocate stack guard pages failed. les messages d'erreur sont émis par JavaThread :: create_stack_guard_pages (), et il appelle os :: guard_memory (). Sous Linux, cette fonction est mprotect ().

    echo 1999999 > /proc/sys/vm/max_map_count
    ou
    sys.vm.max_map_count = 1999999 dans /etc/sysctl.conf pour changer définitivement.

41
maczniak

Informations supplémentaires pour les systèmes Linux modernes (systemd).

Il existe de nombreuses ressources à ce sujet des valeurs qui peuvent avoir besoin d'être modifiées (l'autre réponse est une bonne source pour la plupart d'entre elles); cependant, une nouvelle limite est imposée au moyen de la limite systemd "TasksMax" qui définit pids.max sur le groupe de contrôle.

Pour les sessions de connexion, la valeur par défaut serTasksMax est de 33% de la limite du noyau pids_max (généralement 12 288) et peut être remplacée dans /etc/systemd/logind.conf.

Pour les services, la valeur par défaut DefaultTasksMax est de 15% de la limite du noyau pids_max (généralement 4 915). Vous pouvez le remplacer pour le service en définissant TasksMax dans "systemctl edit" ou mettre à jour DefaultTasksMax dans /etc/systemd/system.conf

10
Trent Lloyd

J'ai rencontré un problème similaire dans un programme Python et les suivants ont fonctionné pour moi. Ceci est basé sur la réponse de maczniak ci-dessus et https://superuser.com/questions/1219960/ Can't-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

J'ai également dû définir DefaultTasksMax dans /etc/systemd/system.conf (ou /etc/systemd/user.conf pour les services gérés par l'utilisateur) à DefaultTasksMax=unlimited.

Systemd applique également une limite pour les programmes exécutés à partir d'un shell de connexion. Ces valeurs par défaut sont de 4096 par utilisateur (seront augmentées à 12288) et sont configurées en tant que UserTasksMax dans la section [Login] de /etc/systemd/logind.conf.

Cela vient de cette question StackExchange . Définir mon UserTasksMax sur UserTasksMax=999999 a fonctionné pour moi.

1
Jonathan