50 votes

Pourquoi la JVM (Sun) a-t-elle une limite supérieure fixe pour l'utilisation de la mémoire (-Xmx)?

Dans l'esprit de la question http://stackoverflow.com/questions/3356005/java-why-does-maxpermsize-existj'aimerais demander pourquoi la JVM de Sun utilise fixe la limite supérieure pour la taille de son allocation de mémoire de la piscine.

La valeur par défaut est de 1/4 de votre RAM physique (avec le haut et le bas de la limite); en conséquence, si vous avez une mémoire-faim application, vous devez modifier manuellement la limite (paramètre -Xmx), ou votre application sera de piètre qualité, possible même en cas de collision avec un OutOfMemoryError.

Pourquoi cette limite fixe, même exister? Pourquoi la JVM de ne pas allouer la mémoire nécessaire, comme des programmes sur la plupart des systèmes d'exploitation?

Cela permettrait de résoudre toute une classe de problèmes communs avec les logiciels Java (juste google pour voir comment de nombreux indices, il existe sur le net sur la résolution de problèmes par la mise -Xmx).

Edit:

Certaines réponses soulignent que cela permettra de protéger le reste du système à partir d'un programme Java avec une fugue fuite de mémoire; sans la limite ce serait mettre l'ensemble du système vers le bas par épuisement de la mémoire. Ce qui est vrai, cependant, il est tout aussi vrai pour n'importe quel autre programme, et de nouveaux Systèmes d'exploitation déjà vous permettre de limiter la quantité maximale de mémoire pour un programm (Linux ulimit, Windows "Objets"). Donc, ce n'est pas vraiment répondre à la question, "Pourquoi la JVM d'une manière différente de la plupart des autres programmes ou d'autres environnements d'exécution?".

24voto

Stephen C Points 255558

Pourquoi cette limite fixe, même exister? Pourquoi la JVM de ne pas allouer la mémoire nécessaire, comme des programmes sur la plupart des systèmes d'exploitation?

La raison n'est PAS que le GC a besoin de savoir avant de la main ce que la taille maximale du tas peut être. La JVM est clairement en mesure de l'expansion de son tas ... jusqu'au maximum ... et je suis sûr que ce serait un relativement petit changement pour le supprimer au maximum. (Après tout, d'autres implémentations Java ce faire.) Et il sera également possible d'avoir un moyen simple de dire "utiliser autant de mémoire que vous aimez" à la JVM.

Je suis sûr que la vraie raison est de protéger le système d'exploitation hôte contre les effets des défauts au niveau des applications Java à l'aide de toute la mémoire disponible. En cours d'exécution avec une vive tas est potentiellement dangereux.

Fondamentalement, de nombreux systèmes d'exploitation (par exemple Windows, Linux) souffrent d'une dégradation des performances graves si une application tente d'utiliser toute la mémoire disponible. Sur Linux par exemple, le système peut thrash mal, entraînant tout sur le fonctionnement du système incroyablement lentement. Dans le pire des cas, le système ne sera pas en mesure de démarrer de nouveaux procédés et processus existants peuvent commencer à s'écraser lorsque le système d'exploitation refuse de leur (légitime) des demandes pour plus de mémoire. Souvent, la seule solution est de redémarrer.

Si la JVM a couru avec une surabondance de segment par défaut, tout le temps quelqu'un a un programme Java avec un stockage de fuite ... ou que tout simplement essayé d'utiliser trop de mémoire ... ils risqueraient de ramener l'ensemble du système d'exploitation.

En résumé, avoir un tas par défaut lié est une bonne chose parce que:

  • il protège la santé de votre système,
  • il encourage les développeurs / utilisateurs à penser à propos de l'utilisation de la mémoire par la "faim" des applications, et
  • il potentiellement permet GC optimisations. (Comme suggéré par d'autres réponses: il est plausible, mais je ne peux pas confirmer cela.)

MODIFIER

En réponse aux commentaires:

  • Il n'importe pas vraiment pourquoi Sun Jvm vivre dans un délimitée tas, là où d'autres applications n'ont pas. Ils le font, et les avantages qui en découlent sont (OMI) clair. Peut-être une question plus intéressante est pourquoi d'autres langues ne pas mettre un lien sur leur tas par défaut.

  • L' -Xmx et ulimit approches sont qualitativement différents. Dans le premier cas, la JVM a pleine connaissance des limites qu'il s'exécute et obtient une chance de gérer son utilisation de la mémoire en conséquence. Dans ce dernier cas, la première chose typique de l'application C le sait, c'est quand un malloc d'échec de l'appel. La réponse typique est de sortir avec un code d'erreur (si le programme vérifie l' malloc suite), ou de mourir avec une erreur de segmentation. OK, une application C pourrait, en théorie, de garder trace de combien de mémoire il a utilisé, et essayer de répondre à la menace d'une mémoire de crise. Mais il serait difficile de travailler.

  • L'autre chose qui est différent au sujet de Java et des applications C/C++ c'est que les premiers ont tendance à être à la fois plus complexe et plus en cours d'exécution. Dans la pratique, cela signifie que les applications Java sont plus susceptibles de souffrir de fuites lentes. Dans le C/C++ cas, le fait que la gestion de la mémoire est plus difficile signifie que les développeurs n'essayez pas de construire des applications de cette complexité. Plutôt, ils sont plus susceptibles de générer (dire) un service complexe par le fait d'avoir un processus d'écoute de la fourche de processus enfants à faire des trucs ... et puis la sortie. Naturellement, cela atténue l'effet des fuites de mémoire dans le processus de l'enfant.

  • L'idée d'une JVM de répondre "adaptative" à des demandes de l'OS, de façon à donner de la mémoire est intéressant. Mais il y a un GROS problème. Afin de donner un segment de mémoire, la JVM d'abord effacer tous accessible objets dans le segment. En règle générale, cela signifie que le garbage collector. Mais l'exécution du ramasse-miettes est la dernière chose que vous voulez faire si le système est dans une mémoire de crise ... car il est presque garanti pour générer une explosion de pagination de mémoire virtuelle.

7voto

sleske Points 29978

Hm, je vais essayer de vous résumer les réponses jusqu'à présent.

Il n'y a pas de raison technique pour la JVM doit avoir une dure limite pour sa taille de segment de mémoire. Il pourrait avoir été mis en œuvre sans l'un, et en fait, de nombreux autres langages dynamiques ne l'avez pas.

Par conséquent, la JVM d'un tas de limite de taille est tout simplement une décision de conception par les réalisateurs. Deuxième deviner pourquoi cela a été fait est un peu difficile, et il peut ne pas être une seule et unique raison. La raison la plus probable est qu'il permet de protéger un système à partir d'un programme Java avec une fuite de mémoire qui, autrement, pourrait épuiser toutes les RAM et causer d'autres applications à bloquer ou le système de thrash.

Soleil pourrait avoir omis de la fonctionnalité et de simplement dit aux gens d'utiliser le système d'exploitation natif de ressources limitation de mécanismes, mais ils voulaient probablement pour toujours avoir une limite, donc ils l'ont mis en œuvre eux-mêmes. En tout cas, la JVM doit être conscient de cette limite (à adapter sa stratégie du gouvernement du canada), alors l'utilisation d'un système d'exploitation natif mécanisme n'aurait pas sauvé beaucoup de travail de programmation.

Aussi, il ya une raison pourquoi une telle limite intégrée est plus important pour la JVM que pour un "normal" programme sans GC (comme un programme C/C++):

À la différence d'un programme avec le manuel de gestion de la mémoire, un programme à l'aide de GC n'est pas vraiment bien défini les besoins en mémoire, même avec fixe d'entrée de données. Il n'a qu'une exigence minimale, c'est à dire la somme des tailles de tous les objets qui sont réellement vivre (accessible) à un point donné dans le temps. Cependant, dans la pratique, un programme auront besoin de plus de mémoire pour contenir morts, mais pas encore GCed objets, parce que le GC ne peut pas collecter tous les objets d'emblée, comme cela causerait trop de GC frais généraux. Donc, GC seulement des coups de pied de temps en temps, et donc une certaine "marge" est nécessaire sur le tas, où les objets morts peuvent attendre de la GC.

Cela signifie que la mémoire nécessaire pour un programme à l'aide de GC est vraiment un compromis entre d'économiser la mémoire et d'avoir une bonne througput (en laissant le GC exécuter en moins souvent). Ainsi, dans certains cas, il peut faire sens pour définir le segment de la limite inférieure de la JVM serait de l'utiliser si elle le pouvait, afin de libérer la mémoire RAM au détriment des performances. Pour ce faire, il doit y avoir un moyen de définir un tas de limite.

5voto

Mark Peters Points 42201

Je pense qu'une partie de cela a à faire avec la mise en œuvre du Garbage Collector (GC). La GC est généralement paresseux, sens, il ne démarre vraiment essayer de récupérer de la mémoire interne lorsque le tas est à sa taille maximale. Si vous n'avez pas de fixer une limite supérieure, l'exécution se ferait un plaisir de continuer à gonfler jusqu'à ce qu'il a utilisé tous les bits de la mémoire sur votre système.

C'est en raison de l'application du point de vue, il est plus performant de prendre plus de ressources que l'effort d'utiliser les ressources que vous avez déjà à la pleine utilisation. Ce qui tend à faire sens pour beaucoup (sinon la plupart) des utilisations de Java, qui est un paramètre du serveur sur lequel l'application est littéralement la seule chose qui compte sur le serveur. Il a tendance à être un peu moins idéal lorsque vous essayez de mettre en œuvre un client en Java, qui sera parmi des dizaines d'autres applications en même temps.

Rappelez-vous que des programmes destinés aux autochtones, le programmeur généralement de la demande, mais aussi explicitement nettoie les ressources. Qui n'est pas généralement vrai avec des environnements qui n'gestion automatique de la mémoire.

3voto

Cela est dû à la conception de la machine virtuelle Java. D'autres machines virtuelles (telles que celles de Microsoft et d'autres sociétés IBM) peuvent utiliser toute la mémoire disponible sur le système, si nécessaire, sans limite arbitraire.

Je crois que cela permet des optimisations GC.

1voto

Daniel Voina Points 1675

Je pense que la limite supérieure de la mémoire est liée au fait que la machine virtuelle est une machine virtuelle.

Comme toute machine physique a une quantité donnée (fixe) de RAM, la VM en a une.

La taille maximale facilite la gestion de la machine virtuelle par le système d'exploitation et garantit des gains de performance (moins de permutation).

La machine virtuelle Java de Sun fonctionne également dans une architecture matérielle assez limitée (systèmes ARM intégrés) et la gestion des ressources y est cruciale.

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