Après avoir lu la question déjà posée sur le sujet et beaucoup de recherches sur Google, je ne parviens toujours pas à avoir une vue claire de -Xms option
Ma question est la suivante: quelle est la différence entre Java -Xms=512m -Xmx=512m
et Java -Xms=64m -Xmx=512m
?
Pour l'instant j'ai la réponse suivante:
La seule différence réside dans le nombre de garbage collection qui seront exécutées lors de l'exécution de mon application et dans le nombre d'allocations de mémoire. Ai-je raison ?
Voici mes raisons pour cette réponse:
Définir l'option -Xms
sur 512m
n'entraîne pas que mon application utilise réellement 512M
de la mémoire physique après le démarrage. Je suppose que cela est lié à la gestion de la mémoire virtuelle des systèmes d’exploitation modernes et aux allocations de pages paresseuses. (J'ai remarqué que la définition de -Xms
sur 512M
ou sur 64M
ne modifie pas du tout la mémoire utilisée initialement indiquée par top sous Linux ou par le gestionnaire de tâches sous Windows)
Quelqu'un peut-il m'aider à comprendre l'impact de cette option Xms
ou à me diriger vers des liens qui m'aideront à le comprendre?
Merci d'avance
Manu
Pour résumer les informations trouvées après le lien: La JVM alloue le montant spécifié par -Xms mais le système d’exploitation n’alloue généralement pas de pages réelles tant qu’elles ne sont pas nécessaires. La JVM alloue donc la mémoire virtuelle spécifiée par Xms mais n'alloue que la mémoire physique en cas de besoin.
Vous pouvez le voir en utilisant Process Explorer par Sysinternals au lieu du gestionnaire de tâches sous Windows.
Il existe donc une réelle différence entre l’utilisation de -Xms64M et de -Xms512M . Mais je pense que la différence la plus importante est celle que vous avez déjà signalée: le garbage collector fonctionnera plus souvent si vous avez vraiment besoin de 512 Mo mais n’a démarré qu’avec 64 Mo .
La JVM commencera par l'utilisation de la mémoire au niveau de segment de mémoire initial. Si maxheap est supérieur, il atteindra la taille maximale car les besoins en mémoire sont supérieurs à sa mémoire actuelle.
Alors,
JVM commence par 512 M, ne redimensionne jamais.
La JVM commence par 64Mo, augmente (jusqu’à 512 au maximum) si mem. les exigences dépassent 64.
En plus des paramètres de tas standard -Xms
et -Xmx
, il est également bon de connaître -XX:PermSize
et -XX:MaxPermSize
, qui sont utilisés pour spécifier la taille de l'espace Perm Gen car, même si vous pouvez avoir de l'espace dans d'autres générations, vous pouvez manquer de mémoire si votre espace permanent est plein. Ce lien contient également une bonne vue d’ensemble des paramètres importants de la JVM .
La machine virtuelle Java redimensionne le segment de manière adaptative, ce qui signifie qu'elle tentera de trouver la taille de segment optimale pour votre application. -Xms et -Xmx spécifient simplement la plage dans laquelle la machine virtuelle Java peut fonctionner et redimensionner le segment de mémoire. Si -Xms et -Xmx ont la même valeur, la taille de segment de mémoire de la JVM restera constante à cette valeur.
Il est généralement préférable de définir -Xmx et de laisser la machine virtuelle trouver la meilleure taille de segment de mémoire, sauf en cas de raison particulière qui justifie de donner un grand segment de mémoire à la machine virtuelle au lancement.
En ce qui concerne le moment où la machine virtuelle Java demande la mémoire au système d'exploitation, je pense que cela dépend de la plate-forme et de la mise en œuvre de la machine virtuelle. J'imagine qu'il ne demanderait pas la mémoire tant que votre application n'en aura pas réellement besoin. -Xmx et -Xms ne réservent que la mémoire.
si vous avez écrit: - Xms512m -Xmx512m quand il commence, Java alloue en ce moment 512m de RAM pour son processus et ne peut pas incrémenter.
-Xms64m -Xmx512m Quand il démarre, Java n'alloue que 64m de RAM pour son processus, mais Java peut incrémenter son occupation de la mémoire pendant 512m.
Je pense que la deuxième chose est préférable, car vous donnez à Java la gestion automatique de la mémoire.
J'ai créé cet exemple de jouet dans scala
, my_file.scala
:
object MyObject {
def main(args: Array[String]) {
var ab = ArrayBuffer.empty[Int]
for (i <- 0 to 100 * 1000 * 1000) {
ab += i
if (i % 10000 == 0) {
println("On : %s".format(i))
}
}
}
}
Je l'ai couru avec:
scala -J-Xms500m -J-Xmx7g my_file.scala
et
scala -J-Xms7g -J-Xmx7g my_file.scala
Il y a certainement des pauses notables dans la version -Xms500m
. Je suis convaincu que les pauses courtes sont des cycles de récupération de place, et les longues sont des allocations de tas.