web-dev-qa-db-fra.com

Compromis rapide entre les options -Xms et -Xmx de Java

Étant donné ces deux commandes

UNE:

$ Java -Xms10G -Xmx10G myjavacode input.txt

B:

$ Java -Xms5G -Xmx5G myjavacode input.txt

J'ai deux questions:

  1. Puisque la commande A réserve plus de mémoire avec ses paramètres, A sera-t-il plus rapide que B?
  2. Comment faire -Xmx et -Xms affecte le processus en cours et la sortie de mon programme?
64
neversaint

Cela dépend du GC utilisé par votre Java est utilisé. Les GC parallèles pourraient fonctionner mieux avec des paramètres de mémoire plus importants - je ne suis toutefois pas un expert en la matière.

En général, moins la mémoire est grande, plus la mémoire doit être GC-ed: il y a beaucoup de place pour les déchets. Cependant, lorsqu'il s'agit d'un GC, celui-ci doit utiliser davantage de mémoire, ce qui peut être plus lent.

21
akarnokd

L'argument -Xmx Définit la taille maximale de la mémoire que le segment de mémoire peut atteindre pour la machine virtuelle Java. Vous devez bien connaître votre programme, voir comment il se comporte sous charge et définir ce paramètre en conséquence. Une valeur faible peut entraîner OutOfMemoryExceptions ou une performance très médiocre si la mémoire de votre programme atteint la taille maximale de ce dernier. Si votre programme est exécuté sur un serveur dédié, vous pouvez définir ce paramètre plus haut car il n’affectera pas les autres programmes.

L'argument -Xms Définit la taille initiale de la mémoire de tas pour la machine virtuelle Java. Cela signifie que lorsque vous démarrez votre programme, la machine virtuelle allouera cette quantité de mémoire instantanément. Ceci est utile si votre programme consomme une grande quantité de mémoire de tas dès le début. Cela évite à la JVM d’augmenter constamment le tas et d’y gagner en performance. Si vous ne savez pas si ce paramètre vous aidera, ne l'utilisez pas.

En résumé, il s'agit d'un compromis que vous devez décider en fonction du comportement de la mémoire de votre programme.

165
bruno conde

J'ai constaté que dans certains cas, trop de mémoire peut ralentir le programme.

Par exemple, j'ai eu un moteur de transformation basé sur l'hibernation qui a démarré lentement à mesure que la charge augmentait. Il s’est avéré que chaque fois que nous obtenions un objet de la base de données, hibernate vérifiait la mémoire pour rechercher des objets qui ne seraient plus jamais utilisés.

La solution consistait à expulser les anciens objets de la session.

Stuart

4
SaSConsul
  1. L'allocation dépend toujours de votre système d'exploitation. Si vous allouez trop de mémoire, vous pourriez finir par avoir des portions chargées dans le swap, ce qui est en effet lent.
  2. Que votre programme fonctionne plus lentement ou plus rapidement dépend des références que la VM doit gérer et nettoyer. Le CPG n'a pas besoin de parcourir la mémoire allouée pour rechercher des objets abandonnés. Il sait que ce sont des objets. et la quantité de mémoire allouée par mappage de référence. Le balayage dépend donc simplement de la taille de vos objets. Si votre programme se comporte de la même manière dans les deux cas, le seul impact sur les performances devrait être VM démarrage , lorsque le VM tente d'allouer la mémoire fournie par votre système d'exploitation et si vous utilisez le swap (ce qui conduit à nouveau à 1.)
3
cafebabe

Il est difficile de dire comment l’allocation de mémoire affectera votre vitesse. Cela dépend de l'algorithme de récupération de place utilisé par la machine virtuelle Java. Par exemple, si votre ramasse-miettes a besoin de faire une pause pour effectuer une collecte complète, si vous avez 10 fois plus de mémoire que nécessaire, le collecteur aura 10 poubelles de plus à nettoyer.

Si vous utilisez Java 6, vous pouvez utiliser la commande jconsole (située dans le répertoire bin du dossier jdk) pour attacher à votre processus et observer le comportement du collecteur. En général, les collecteurs sont très intelligents et vous n'aurez besoin d'aucun réglage, mais si vous en avez besoin, vous disposez de nombreuses options pour optimiser le processus de collecte.

2
pfranza
> C:\Java -X

-Xmixed           mixed mode execution (default)
-Xint             interpreted mode execution only
-Xbootclasspath:<directories and Zip/jar files separated by ;>
                  set search path for bootstrap classes and resources
-Xbootclasspath/a:<directories and Zip/jar files separated by ;>
                  append to end of bootstrap class path
-Xbootclasspath/p:<directories and Zip/jar files separated by ;>
                  prepend in front of bootstrap class path
-Xnoclassgc       disable class garbage collection
-Xincgc           enable incremental garbage collection
-Xloggc:<file>    log GC status to a file with time stamps
-Xbatch           disable background compilation
-Xms<size>        set initial Java heap size
-Xmx<size>        set maximum Java heap size
-Xss<size>        set Java thread stack size
-Xprof            output cpu profiling data
-Xfuture          enable strictest checks, anticipating future default
-Xrs              reduce use of OS signals by Java/VM (see documentation)
-Xcheck:jni       perform additional checks for JNI functions
-Xshare:off       do not attempt to use shared class data
-Xshare:auto      use shared class data if possible (default)
-Xshare:on        require using shared class data, otherwise fail.

Le -X Les options ne sont pas standard et peuvent être modifiées sans préavis.

(copier coller)

1
Virus

C'était toujours la question que j'avais quand je travaillais sur l'une de mes applications, ce qui créait un nombre énorme de threads par requête.

C'est donc une très bonne question et elle comporte deux aspects:
1. Si mes valeurs Xms et Xmx doivent être identiques
- La plupart des sites Web et même les documents Oracle suggèrent qu'il en soit de même. Cependant, je suggère d’avoir 10 à 20% de mémoire tampon entre ces valeurs pour donner à votre application une option de redimensionnement de segment de mémoire en cas de forte augmentation soudaine du trafic OR une fuite de mémoire accidentelle.

2. Si je dois démarrer mon application avec une taille de segment inférieure
- Alors voici le problème - peu importe ce que GC Algo utilise (même G1), un gros tas a toujours un compromis. L’objectif est d’identifier le comportement de votre application avec la taille de segment de mémoire que vous pouvez autoriser à suspendre votre CPG en termes de latence et de débit.
- Par exemple, si votre application a beaucoup de threads (chaque thread a une pile de 1 Mo dans la mémoire native et non dans le tas) mais n'occupe pas d'espace objet lourd, alors je suggère d'avoir une valeur inférieure de Xms.
- Si votre application crée un grand nombre d'objets avec un nombre croissant de threads, identifiez la valeur de Xms que vous pouvez définir pour tolérer ces pauses STW. Cela signifie qu’il faut identifier le temps de réponse maximum de vos demandes entrantes que vous pouvez tolérer et accorder la taille de tas minimale.

1
user1540256