JVM 64 bits limitée à 300 Go de mémoire?

j'essaie d'exécuter une application Java sur un environnement de cluster computing (IBM LSF exécutant CentOS version 6.2 Final) qui peut me fournir jusqu'à 1 to D'espace de mémoire vive.

je pourrais créer une JVM avec JUSQU'à 300 Go de mémoire maximale (Xmx), bien que j'ai besoin de plus que cela (je peux fournir des détails, si demandé).

cependant, il semble impossible de créer une JVM avec plus de 300 Go de mémoire maximale en utilisant L'option Xmx. Pour être plus spécifique, j'ai le classique message d'erreur:

Une erreur

s'est produite lors de l'initialisation de VM.

ne pouvait pas réserver assez d'espace pour un tas d'objets.

les détails de mon JVM (64 bits) sont ci-dessous:

OpenJDK Runtime Environment (IcedTea6 1.10.6) (rhel-1.43.1.10.6.el6_2-x86_64)

OpenJDK 64-Bit Server VM (build 20.0 - b11, mixed mode)

j'ai aussi essayé avec un Java 7 JVM 64 bits, mais j'ai eu exactement le même problème.

de plus, j'ai essayé de créer une JVM pour gérer un HelloWorld.jar, mais la création JVM échoue quand même si vous demandez plus que-Xmx300G, donc je ne pense pas que cela ait quoi que ce soit à voir avec l'application spécifique.


est-ce que quelqu'un sait pourquoi je ne peux pas créer une JVM avec plus de 300G de mémoire max?

quelqu'un Peut s'il vous plaît suggérer une solution?

59
demandé sur critichu 2014-03-28 15:11:33

5 réponses

je ne peux penser à un couple d'explications possibles:

  • "D'autres applications sur votre système utilisent tellement de mémoire qu'il n'y a pas 300 Go disponible dès maintenant .

  • il pourrait y avoir une limite de ressources sur la taille de mémoire par processus. Vous pouvez vérifier cela en utilisant ulimit . (Notez que selon ce bug , vous obtiendrez le message d'erreur si la limite de ressources par processus empêche la JVM d'allouer les régions tas.)

  • il est également possible qu'il s'agisse d'un problème de "sur-commit"; par exemple, si votre application est virtuelle et que le système dans son ensemble ne peut pas répondre à la demande parce qu'il y a trop de concurrence d'autres virtualités.


quelques autres idées suggérées sont peu probables (IMO):

  • il est peu probable que la commutation de la JRE fasse une différence. Je n'ai jamais entendu parler ou vu de limites de mémoire arbitraires dans des JVM 64 bits spécifiques.

  • Il est peu probable en raison de ne pas avoir assez de contigu mémoire. Certainement contigu de mémoire physique n'est pas requise. La seule possibilité pourrait être espace contigu sur le dispositif de swap, mais je ne me souviens pas que ce soit un problème pour Linux typique OS.


Quelqu'un peut-il Suggérer une solution?

  • cochez la case ulimit .

  • écrivez un programme C minuscule qui tente de malloc beaucoup de mémoire et de voir combien qui peut allouer avant qu'il n'échoue.

  • demander au système (ou l'hyperviseur) administrateur pour obtenir de l'aide.

18
répondu Stephen C 2014-03-30 11:09:29

(modifié, voir la section ajoutée sur l'espace de pagination)

SHMMAX et SHMALL

étant donné que vous utilisez CentOS, vous avez peut-être rencontré un problème similaire concernant le paramétrage du noyau SHMMAX et SHMALL tel que décrit ici pour la configuration de la base de données Oracle . Sous ce même lien se trouve un exemple de calcul pour obtenir et définir le réglage correct SHMALL .

Mémoire contiguë

certains utilisateurs ont déjà signalé qu'il n'y a pas assez de mémoire contiguë disponible, d'autres ont dit que ce n'est pas pertinent.

Je ne suis pas certain que la JVM sur CentOS nécessite un bloc de mémoire contigu. selon SAS , la mémoire fragmentée peut empêcher votre JVM au démarrage avec un grand max Xmx ou démarrer Xms paramètre de mémoire, mais d'autres revendications sur l'internet disent qu'il ne question. J'ai essayé de le prouver ou de le déballer sur mon poste de travail Windows de 48 Go, mais j'ai réussi à démarrer la JVM avec un réglage initial et maximal de 40 Go. Je suis assez sûr qu'aucun bloc contigu de cette taille n'était disponible, mais les JVM sur différents OS peuvent se comporter différemment, parce que la gestion de la mémoire peut être différente par OS (C'est-à-dire que Windows cache typiquement les adresses physiques des processus individuels).

trouver le plus grand bloc de mémoire contigu

utiliser /proc/meminfo pour trouver le plus grand bloc mémoire contigu disponible, voir la valeur sous VmAllocChunk . voici un guide et une explication de toutes les valeurs. Si la valeur que vous voyez là est plus petite que 300 Go, essayez une valeur qui tombe juste sous la valeur de VmAllocChunk .

cependant, généralement ce nombre est plus élevé que la mémoire physique disponible (parce que c'est la virtuel valeur mémoire disponible), il peut vous donner un faux positif. C'est la valeur que vous pouvez réserver, mais une fois que vous commencer à l'utiliser, elle peut exiger de permutation. Vous devez donc également vérifier les valeurs MemFree et Inactive . À l'inverse, vous pouvez aussi regarder la liste entière et voir quelles valeurs ne dépassent pas 300 Go.

autres options d'accord que vous pouvez vérifier pour 64 bits JVM

Je ne suis pas sûr pourquoi vous semblez frapper un problème de limite de mémoire à 300 Go. Pendant un moment j'ai pensé que vous pourriez avoir atteint un maximum de pages. Avec la valeur par défaut de 4kB, 300GB donne 78,643,200 pages. Ça ne ressemble pas à un numéro magique bien connu. Si, par exemple, 2^24 est le maximum, alors 16,777,216 pages, ou 64 Go devrait être votre maximum allocable théorique.

cependant, supposons pour le bien de l'argument que vous avez besoin de plus grandes pages (qui est, comme il s'avère, mieux pour la performance de grandes applications Java de mémoire), vous devriez consulter ce page de manuel sur JBoss , qui explique comment utiliser -XX:+UseLargePages et mettre kernel.shmmax (il est encore là), vm.nr_hugepages et vm.huge_tlb_shm_group (pas sûr que ce dernier est nécessaire).

le Stress de votre système

D'autres l'ont déjà suggéré. Pour découvrir que le problème réside dans la JVM et non dans L'OS, vous devriez le tester. Un outil que vous pourriez utiliser est Stresslinux . dans ce tutoriel , vous trouverez quelques options que vous pouvez utiliser. La commande suivante vous intéresse particulièrement:

stress --vm 2 --vm-bytes 300G --timeout 30s --verbose

si cette commande échoue, ou bloque votre système, vous savez que le système d'exploitation limite l'utilisation de cette quantité de mémoire. Si elle réussit, nous devrions essayer de modifier la JVM de manière à ce qu'elle puisse utiliser la mémoire disponible.

MODIFIER Apr6: vérification de l'espace de swap

il n'est pas rare que les systèmes avec de très grandes les tailles de mémoire, utilisez peu ou pas d'espace d'échange. Pour de nombreuses applications, cela peut ne pas être un problème, mais la JVM exige que l'espace de swap disponible soit plus grand que la taille de mémoire demandée. Selon ce rapport de bug , la JVM tentera d'augmenter l'espace de swap lui-même, cependant, comme certaines réponses dans ce fil de SO suggère , la JVM peut ne pas être toujours capable de le faire.

donc: vérifier le swap actuellement disponible espace avec cat /proc/swaps # free et, si elle est inférieure à 300 Go, suivre les instructions sur cette page de manuel CentOS pour augmenter l'espace de pagination pour votre système.

Note 1: Nous pouvons déduire de bugreport #4719001 qu'un bloc contigu d'espace d'échange disponible n'est pas une nécessité. Mais si vous n'êtes pas sûr, supprimer tout espace d'échange et de le recréer , qui devrait supprimer toute fragmentation.

Note 2: j'ai vu plusieurs billets comme celui-ci reporting 0MB swap space et pouvoir exécuter la JVM. C'est probablement dû au fait que la JVM augmente l'espace d'échange lui-même. Encore ne fait pas de mal d'essayer d'augmenter l'espace d'échange en main pour savoir si cela résout votre problème.

conclusion prématurée

je me rends compte que non de ce qui précède est une réponse hors-de-la-boîte à votre question. J'espère que cela vous donnera quelques conseils sur ce que vous pouvez essayer de faire fonctionner votre JVM. Vous pouvez également essayer d'autres JVM, si le problème se révèle être une limite de la JVM que vous utilisez actuellement, mais d'après ce que j'ai lu jusqu'à présent, aucune limite ne devrait être imposée pour les JVM 64 bits.

que vous obtenez l'erreur droite sur l'initialisation de la JVM me conduit à croire que le problème n'est pas avec la JVM, mais avec L'OS pas être en mesure de respecter la réservation des 300 Go de mémoire.

mes propres tests ont montré que la JVM peut accéder à toute la mémoire virtuelle, et ne se soucie pas de la quantité de mémoire physique disponible. Il serait étrange que la mémoire virtuelle soit plus basse que la mémoire physique, mais le paramètre VmAllocChunk devrait vous donner un indice dans cette direction (il est généralement beaucoup plus grand).

15
répondu Abel 2017-05-23 12:09:49

si vous avez un coup d'oeil à la section FAQ section de Java HotSpot VM, il est mentionné que sur les Vm 64 bits, il n'y a que 64 bits d'adresse à travailler avec et donc la taille maximale Java tas dépend de la quantité de mémoire physique et l'espace de swap présent sur le système.

si vous calculez théoriquement alors vous pouvez avoir une mémoire de 18446744073709551616 MB , mais il ya au-dessus de la limitation.

Vous devez utiliser la commande -Xmx pour définir la taille maximale des tas pour JVM, par défaut , Java utilise 64 + 30% = 83,2 MB sur JVM 64 bits.

j'ai essayé en bas de commande sur ma machine et elle semblait fonctionner correctement.

java -Xmx500g com.test.TestClass

j'ai aussi essayé de définir un maximum de tas en teraoctets mais cela ne fonctionne pas.

4
répondu Shishir Kumar 2014-03-28 13:09:29

exécutez ulimit-a comme utilisateur du processus JVM et vérifiez que votre noyau ne limite pas la taille de votre mémoire maximale. Vous devrez peut-être éditer /etc/security/limit.conf

0
répondu user3100381 2014-03-28 14:16:02

selon cette discussion , LSF ne regroupe pas la mémoire des Noeuds en un seul espace partagé. Vous utilisez autre chose. Lisez la documentation de quelque chose, parce qu'il est possible qu'il ne puisse pas faire ce que vous lui demandez de faire. En particulier, il peut ne pas être en mesure d'allouer une seule région contiguë de mémoire qui s'étend sur tous les noeuds. Habituellement, ce n'est pas nécessaire, comme une demande de nombreux appels à malloc. Mais la JVM, pour simplifier les choses pour lui-même, veut allouer (ou réserver) une seule région contiguë pour l'ensemble du tas en appelant effectivement malloc une seule fois. Ou cela pourrait être quelque chose d'autre lié à ce que vous utilisez pour émuler une machine à mémoire partagée géante.

0
répondu Aleksandr Dubinsky 2017-04-13 12:53:54