50 votes

Java refuse de démarrer - Impossible de réserver suffisamment d'espace pour le tas d'objets

Arrière-plan

Nous avons une piscine d'environ 20 linux lames. Certains sont en cours d'exécution Suse, certains sont sous Redhat. TOUT part de NAS de l'espace qui contient 3 dossiers:

  • /NAS/app/java - un lien symbolique qui pointe vers une installation d'un JDK Java. Actuellement la version 1.5.0_10
  • /NAS/app/lib - un lien symbolique qui pointe vers une version de notre application.
  • /NAS/données - répertoire où notre production est écrit

Toutes nos machines ont 2 processeurs (hyperthread) avec 4 go de mémoire vive et 4 go d'espace de swap. Nous limitons le nombre d'emplois de " chaque machine peut traiter à un moment donné à 6 (ce nombre aura besoin de changement, mais cela ne veut pas entrer dans le problème actuel, de sorte s'il vous plaît ignorer pour le moment).

Certains de nos emplois définir un Max taille du Segment de mémoire de 512 mo, d'autres de réserver un Max de la taille du Segment de 2048. Encore une fois, nous nous rendons compte que nous pourrions aller au-dessus de notre mémoire disponible si 6 travaux ont commencé sur la même machine avec la taille de segment de mémoire la valeur 2048, mais à notre connaissance, cela n'a pas encore eu lieu.

Le Problème

De temps à un Travail échoue immédiatement avec le message suivant:

Error occurred during initialization of VM
Could not reserve enough space for object heap
Could not create the Java virtual machine.

Nous avons utilisé de la craie ce jusqu'à de trop nombreuses tâches qui s'exécutent en même temps sur la même machine. Le problème est arrivé assez rarement (PEUT-être une fois par mois) à laquelle nous venons de le redémarrer et tout irait bien.

Le problème a récemment eu bien pire. Tous nos travaux, qui demande un max de la taille du segment de 2048m échouer immédiatement presque tous les temps et ils doivent obtenir redémarré plusieurs fois avant de se terminer.

Nous sommes allés à des machines individuelles et a essayé de les exécuter manuellement avec le même résultat.

Débogage

Il s'avère que le problème n'existe que pour notre SuSE boîtes. La raison pour laquelle il a été se passe de plus en plus fréquemment est parce que nous avons été l'ajout de plus de machines, et les nouveaux sont de SuSE.

"cat /proc/version' sur SuSE boîtes de nous donner:

Linux version 2.6.5-7.244-bigsmp (geeko@buildhost) (gcc version 3.3.3 (SuSE Linux)) #1 SMP Mon Dec 12 18:32:25 UTC 2005

"cat /proc/version' sur la RedHat boîtes de nous donner:

Linux version 2.4.21-32.0.1.ELsmp (bhcompile@bugs.build.redhat.com) (gcc version 3.2.3 20030502 (Red Hat Linux 3.2.3-52)) #1 SMP Tue May 17 17:52:23 EDT 2005

'uname -a' nous donne les éléments suivants sur les DEUX types de machines:

UTC 2005 i686 i686 i386 GNU/Linux

Pas de travaux en cours d'exécution sur la machine, et pas d'autres processus sont en utilisant beaucoup de mémoire. Tous les processus en cours d'exécution pourrait être à l'aide de 100 mo au total.

'top' actuellement le suivant:

Mem:   4146528k total,  3536360k used,   610168k free,   132136k buffers
Swap:  4194288k total,        0k used,  4194288k free,  3283908k cached

'vmstat" actuellement le suivant:

procs -----------memory---------- ---swap-- -----io---- --system-- ----cpu----
r  b   swpd   free   buff  cache   si   so    bi    bo   in    cs us sy id wa
0  0      0 610292 132136 3283908    0    0     0     2   26    15  0  0 100  0

Si nous le coup d'envoi d'un travail avec la ligne de commande suivante (Max Tas de 1850mb) il commence bien:

java/bin/java -Xmx1850M -cp helloworld.jar HelloWorld
Hello World

Si nous remonter le max de la taille du segment de 1875mb il échoue:

java/bin/java -Xmx1875M -cp helloworld.jar HelloWorld
Error occurred during initialization of VM
Could not reserve enough space for object heap
Could not create the Java virtual machine.

Il est clair que la mémoire utilisée est mise en mémoire-Tampon/mise en Cache et c'est pourquoi si peu est affiché comme "gratuits". Ce n'est pas clair, c'est pourquoi il est un lieu magique 1850mb ligne où quelque chose de plus élevé que Java ne peut pas démarrer.

Toutes les explications serait grandement apprécié.

21voto

Jon Bright Points 6834

Vous utilisez une version 32 bits de l'OS, de sorte que vous allez voir des limites sur la taille totale en raison de cela. D'autres réponses ont couvert plus en détail, donc je vais éviter de répéter leurs informations.

Un comportement que j'ai remarqué avec nos serveurs récemment, c'est que la spécification d'une taille maximale du tas avec -Xmx tout en ne spécifiant pas un minimum de taille de segment de mémoire avec -Xms conduirait à Java server VM immédiatement en essayant de répartir la totalité de la mémoire nécessaire pour la taille maximale du tas. Et bien sûr, si l'application se lève pour que la taille du segment, c'est la quantité de mémoire que vous aurez besoin. Mais les chances sont, vos applications pourront être de commencer avec un rapport comparativement petits tas et peut exiger que le plus grand segment de mémoire à un moment plus tard. En outre, en indiquant le minimum de taille de segment de mémoire vous permettra de démarrer votre application de commencer avec un petit tas de croître progressivement ce segment.

Tout cela ne va pas vous aider à augmenter votre taille maximale du tas, mais j'ai pensé qu'il pourrait l'aider, alors...

15voto

Luca Tettamanti Points 2757

Comme suggéré dans d'autres réponses, le problème est provoqué par l'épuisement de l'espace d'adressage virtuel. 32 bits linux userspace programme est généralement limité à 3 go de COMME; le reste de 1 GO est utilisée par le noyau (raison: depuis le sommet de 1 go est le noyau fixe de cartographie, il n'est pas nécessaire de toucher à la table des pages lors de la diffusion d'appels).

RHEL noyaux, cependant, de mettre en œuvre le soi-disant 4 GO/4 GO de split où la totalité de 4GO COMME est disponible à l'espace utilisateur processus au prix d'une légère gestion d'exécution (le noyau vit dans un autre de 4 go et virtuels)

8voto

MarkR Points 37178

L'exécution d'un 32-bit OS est une erreur; vous devriez certainement mettre à niveau dans les plus brefs délais.

Je ne sais pas si Java nécessite son segment à être dans un seul espace contigu, mais si elle le fait, en demandant de 1,8 G de tas sur une version 32 bits de zone sonne comme un défi de taille. Vous êtes en supposant qu'il ya un morceau de l'espace d'adresse, près de la moitié de cela, libre à la JVM au moment du démarrage.

Selon ce que les autres bibliothèques sont chargées à l'époque, il y a peut-être pas. Les bibliothèques peuvent allouer de la mémoire de n'importe où qu'ils aiment, de sorte qu'il pourrait fragmenter votre adresse espace suffisamment de 1,8 G n'est pas disponible en un seul morceau.

Il n'y a que la 3G espace d'adressage max disponible sur Linux 32 bits de toute façon. Les bibliothèques et la JVM elle-même utilise certains de commencer avec.

3voto

Andrew Points 160

ulimit max memory size et mémoire virtuelle configurée pour illimité?

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X