J'exécute une application conteneurisée Java dans Kubernetes.
Afin de faire de la mémoire de réserve jvm selon les spécifications du conteneur, les drapeaux -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap
Doit être réglé.
Si ces deux indicateurs sont définis avec les indicateurs Xms et Xmx, quel serait le comportement du jvm? Un drapeau écrase-t-il l'autre?
Par exemple, si nous avions Java -XX:+UnlockExperimentalVMOptions -XX:+UseCGroupMemoryLimitForHeap -Xms -Xms2500M -Xmx2500M -jar myjar.jar
dans un pod avec des limites de conteneur 4Gi pour les demandes et 4Gi pour les réponses, dans une machine hôte qui a 128 Go de mémoire, combien de mémoire la JVM réserverait-elle?
L'indicateur -Xmx remplace l'indicateur -XX: + UseCGroupMemoryLimitForHeap.
L'indicateur -XX: + UseCGroupMemoryLimitForHeap permet à la machine virtuelle Java de détecter la taille maximale du segment dans un conteneur.
L'indicateur -Xmx définit la taille maximale du tas sur une taille fixe.
Pour répondre à votre exemple, la JVM réserverait 2500M d'espace de tas. Il y aura une utilisation supplémentaire de la mémoire pour les éléments non tas et jvm.
Pour affiner votre utilisation de la mémoire dans un conteneur, vous pouvez utiliser l'indicateur -XX: MaxRAMFraction. Voir cet article: https://blog.csanchez.org/2017/05/31/running-a-jvm-in-a-container-without-getting-killed/
Pensez-y de cette façon, avant que UseCGroupMemoryLimitForHeap
a été ajouté, vous pouvez spécifier Xmx
avec une valeur supérieure à celle de votre pod (il ne semble que sur l'hôte mémoire, pas le pod lui-même), éventuellement tué. Par défaut, c'était 1/4 de la mémoire s'il n'était pas spécifié. Cela se produit car le tas est calculé comme suit:
heap = memory / MaxRAMFraction
Et en cours d'exécution:
Java -XX:+PrintFlagsFinal | grep MaxRAMFraction
révélerait que MaxRAMFraction = 4
.
Maintenant que UseCGroupMemoryLimitForHeap
a été ajouté, vous pouvez dire combien de tas du pod lui-même seront pris. Par défaut, c'est toujours 1/4; mais vous pouvez l'ajuster via MaxRAMFraction
, bien sûr.
Si vous spécifiez les deux arguments, Xms
l'emporte. toujours. Et 1) c'est assez logique (comme UseCGroupMemoryLimitForHeap
est plus spécifique que Xmx
) 2) c'est exactement prouvé par mes expériences tout à l'heure. Quel que soit l'ordre dans lequel ils sont spécifiés, Xmx
l'emporte toujours.