web-dev-qa-db-fra.com

Est-ce que -XX: MaxRAMFraction = 1 est sans danger pour la production dans un environnement confiné?

Java 8/9 apporte le support pour -XX:+UseCGroupMemoryLimitForHeap (avec -XX:+UnlockExperimentalVMOptions). Ceci définit -XX:MaxRAM à la limite de mémoire du groupe de contrôle. Par défaut, la JVM alloue environ 25% de la RAM maximale, car -XX:MaxRAMFraction la valeur par défaut est 4.

Exemple:

MaxRAM = 1g
MaxRAMFraction = 4
JVM is allowed to allocate: MaxRAM / MaxRAMFraction = 1g / 4 = 256m

Utiliser seulement 25% du quota semble être une perte de temps pour un déploiement qui consiste (généralement) en un seul processus JVM. Alors maintenant, les gens mis -XX:MaxRAMFraction=1, la JVM est donc théoriquement autorisée à utiliser 100% de MaxRAM.

Pour l'exemple 1g, cela se traduit souvent par une taille de tas d'environ 900 m. Cela semble un peu élevé - il n’ya pas beaucoup de place disponible pour la machine virtuelle Java ou d’autres éléments tels que des shells distants ou des tâches hors processus.

Alors est-ce que cette configuration (-XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -XX:MaxRAMFraction=1) considéré comme sûr, voire même comme pratique exemplaire? Ou devrais-je toujours choisir à la main -Xmx, -Xms, -Xss etc?

27
atamanroman

Nous avons fait quelques tests simples qui ont montré que le réglage -XX:MaxRAM=$QUOTA et -XX:MaxRAMFraction=1 résulte en des conteneurs tués sous charge. La machine virtuelle Java alloue plus de 900 millions de tas, ce qui est beaucoup trop. -XX:MaxRAMFraction=2 semble sûr (ish).

N'oubliez pas que vous pouvez laisser de la marge pour d'autres processus, tels que l'obtention d'un shell de débogage (docker exec) ou diagnostics dans le conteneur.


Edit: nous avons écrit ce que nous avons appris en détail dans un article . Citations d'argent:

TL'DR: Java) La gestion et la configuration de la mémoire sont toujours complexes. Bien que la JVM puisse lire les limites de la mémoire du groupe de contrôle et s'adapter Utilisation de la mémoire en conséquence puisque Java 9/8u131, ce n’est pas une solution miracle. Vous devez savoir quoi -XX:+UseCGroupMemoryLimitForHeap le fait et vous devez ajuster certains paramètres pour chaque déploiement. Sinon, vous risquez de gaspiller des ressources et de l'argent ou de faire tuer vos conteneurs au pire moment possible. -XX:MaxRAMFraction=1 est particulièrement dangereux. Java 10+ apporte de nombreuses améliorations mais nécessite toujours une configuration manuelle. Pour plus de sécurité, chargez vos données en test.

et

La solution la plus élégante consiste à mettre à niveau vers Java 10+. Java 10 est obsolète -XX:+UseCGroupMemoryLimitForHeap (11) et introduit -XX:+UseContainerSupport (12), qui le remplace. Il introduit également -XX:MaxRAMPercentage _ (13) qui prend une valeur comprise entre 0 et 100. Ceci permet un contrôle fin du montant de RAM, la JVM est autorisée à l'allouer. Depuis +UseContainerSupport est activé par défaut, tout devrait fonctionner immédiatement.


Edit # 2: nous avons écrit un peu plus à propos de -XX:+UseContainerSupport

Java 10 introduit +UseContainerSupport (activé par défaut) qui oblige la machine virtuelle Java à utiliser des valeurs par défaut saines dans un environnement de conteneur. Cette fonctionnalité a été rétroportée sur Java 8 depuis 8u191, ce qui permet potentiellement à un énorme pourcentage de Java de déploiements dans la nature de configurer correctement leur mémoire.

24
atamanroman

Le récent Oracle-jdk-8 (8u191) apporte les options suivantes pour permettre aux utilisateurs du conteneur Docker d’obtenir un contrôle plus fin de la quantité de mémoire système qui sera utilisée pour le Java Heap:

-XX:InitialRAMPercentage
-XX:MaxRAMPercentage
-XX:MinRAMPercentage

Trois nouvelles options de machine virtuelle Java ont été ajoutées pour permettre aux utilisateurs du conteneur Docker d’obtenir un contrôle plus fin de la quantité de mémoire système qui sera utilisée pour le Java Heap:

-XX: InitialRAMPercentage -XX: MaxRAMPercentage -XX: MinRAMPercentage Ces options remplacent les formulaires de fraction obsolètes (-XX: InitialRAMFraction, -XX: MaxRAMFraction et -XX: MinRAMFraction).

Voir https://www.Oracle.com/technetwork/Java/javase/8u191-relnotes-5032181.html

10
a.l.