32 votes

Pourquoi la taille maximale du segment de mémoire Java est-elle fixée?

Il n'est pas possible d'augmenter la taille maximale de Java tas après le VM a commencé. Quelles sont les raisons techniques à cela? Faire la collecte des ordures algorithmes reposent sur un montant fixe de mémoire pour travailler avec? Ou est-ce pour des raisons de sécurité, pour empêcher une application Java à partir de DOS avec d'autres applications sur le système en consommant toute la mémoire disponible?

23voto

Joshua McKinnon Points 12379

Dans le Soleil de la JVM, le dernier, je le savais, l'ensemble du tas doit être affecté dans une zone contiguë de l'espace d'adresse. J'imagine que pour de grandes valeurs de tas, c'est assez dur à ajouter à votre espace d'adresse après le démarrage tout en veillant à ce qu'il reste contigus. Vous avez probablement besoin d'obtenir au démarrage, ou pas du tout. Ainsi, il est fixe.

Même si elle n'est pas utilisée immédiatement, l'espace d'adressage pour l'ensemble du segment de mémoire est réservé au démarrage. S'il est impossible de réserver un assez grand bloc contigu de l'espace d'adressage pour la valeur de -Xmx que vous le passer, il ne pourra pas démarrer. C'est pourquoi il est difficile d'allouer >1.4 GO tas sur Windows 32 bits, car il est difficile de trouver contiguë de l'espace d'adresse dans cette taille ou plus grand, puisque certaines Dll à charger dans certains endroits, la fragmentation de l'espace d'adressage. Ce n'est pas vraiment un problème quand vous allez 64 bits, car il ya tellement de beaucoup plus d'espace d'adressage.

Ce n'est presque certainement pour des raisons de performances. Je ne pouvais pas trouver un formidable lien détaillant plus loin, mais voici une bien jolie citation de Peter Kessler (lien complet - assurez-vous de lire les commentaires) que j'ai trouvé lors de la recherche. Je crois qu'il travaille sur la JVM de Sun.

La raison nous avons besoin d'une mémoire contiguë région de le tas, c'est que nous avons un tas de côté les structures de données indexé par (mise à l'échelle) les compensations de l' début de la tas. Par exemple, nous la piste de l'objet de référence mises à jour avec une "carte de marque array" qui a un octet pour chaque 512 octets de mémoire. Lorsque nous stocker une référence dans le tas, nous avons pour marquer l'octet correspondant à la carte de marque de tableau. Nous décalage à droite de l' adresse de destination de la boutique et l'utiliser à l'index de la carte de marque de tableau. Le plaisir d'adressage de l'arithmétique jeux vous ne peut pas le faire en Java que vous obtenez à l' (ont pour :-) jouer en C++.

C'était en 2004, je ne suis pas sûr de ce qui a changé depuis, mais je suis assez sûr qu'il détient toujours. Si vous utilisez un outil comme Process Explorer, vous pouvez voir que la taille virtuelle (ajouter la taille virtuelle et privé de la taille de la mémoire colonnes) de l'application Java intègre le total de la taille de segment de mémoire (ainsi que d'autres besoin d'espace, sans doute) du point de démarrage, même si la mémoire "utilisé" par le processus sera pas le cas à proximité jusqu'à ce que le tas commence à se remplir...

8voto

x4u Points 7436

Historiquement, il y a une raison pour cette limitiation, qui était de ne pas permettre à des Applets dans le navigateur de manger de tous les utilisateurs de la mémoire. La machine virtuelle Microsoft qui n'a jamais eu une telle limitiation réellement permis de faire ce qui pourrait conduire à une sorte de Déni de Service attaque contre l'ordinateur des utilisateurs. C'était seulement il y a un an que le Soleil a introduit dans la mise à Jour 1.6.0 10 VM un moyen de laisser les applets de spécifier la quantité de mémoire qu'ils veulent (limitée à une certaine part fixe de la mémoire physique) au lieu de les limiter à 64 mo de même sur les ordinateurs qui ont 8 GO ou plus disponible.

Maintenant, depuis la JVM a évolué il aurait été possible de se débarrasser de cette limitation, lorsque la VM est pas en cours d'exécution à l'intérieur d'un navigateur, mais le Soleil est évidemment jamais considéré comme une question de haute priorité, même si il ya eu de nombreux rapports de bogue été déposé pour permettre enfin aux tas de croître.

4voto

Yishai Points 42417

Je pense que le court, sarcastique, la réponse est parce que le Soleil n'a pas trouvé ça vaut le temps et les coûts de développement.

La plus convaincante des cas d'utilisation pour une telle fonctionnalité est sur le bureau, l'OMI, et Java a toujours été une catastrophe sur le bureau quand il s'agit de la mécanique de lancement de la JVM. Je soupçonne que ceux qui pensent le plus à propos de ces questions ont tendance à se concentrer sur le côté serveur et afficher tous les autres détails laissé aux indigènes des wrappers. C'est une décision regrettable, mais il faut juste être l'un des points de décision au moment de décider sur la bonne plate-forme pour une application.

3voto

Michael Wiles Points 7570

Mon impression est que cela a à voir avec la gestion de la mémoire à l'égard des autres applications en cours d'exécution sur le système d'exploitation.

Si vous définissez la taille maximale du tas, par exemple, la quantité de RAM de la boîte, vous laissez efficacement la VM décider de la quantité de mémoire qu'elle nécessite (jusqu'à cette limite). Le problème, c'est que la machine virtuelle pourrait effectivement paralyser la machine, il est en cours d'exécution, car il faudra plus de la mémoire sur la boîte avant qu'il ne décide qu'il a besoin de collecter les ordures.

Lorsque vous spécifiez max de la taille du segment, ce que vous dites à la VM est, vous êtes autorisé à utiliser cette quantité de mémoire avant de vous avez besoin pour commencer la collecte des ordures. Vous ne pouvez pas avoir plus parce que si vous prenez plus que les autres applications en cours d'exécution sur la boîte de ralentir et vous allez commencer à bascule vers le disque si vous utilisez plus que cela.

Également être conscients du fait qu'ils sont deux valeurs à l'égard de la mémoire, qui est en cours "taille de segment de mémoire" et "max taille de segment de mémoire". Le courant taille de segment de mémoire est la mémoire la taille de segment de mémoire est en train d'utiliser et, si elle nécessite plus il peut redimensionner le tas, mais il ne peut pas redimensionner le tas au-dessus de la valeur de la taille maximale du tas.

2voto

Mike Houston Points 4320

D'IBM et de la performance conseils de réglages (donc peut-être pas directement applicables au Soleil VMs)

La Java tas de paramètres influencent le comportement de la collecte des ordures. L'augmentation de la taille de segment de mémoire prend en charge plus de la création de l'objet. Parce qu'un grand tas prend plus de temps à se remplir, l'application s'exécute plus avant la collecte des ordures se produit. Cependant, un plus grand segment de mémoire prend également plus de temps pour compacter et les causes de la collecte des ordures à prendre plus de temps.

La JVM a des seuils pour la gestion de la JVM de stockage. Lorsque les seuils sont atteints, le garbage collector est appelé à libérer de l'espace de stockage inutilisé. Par conséquent, la collecte des ordures peut provoquer une dégradation significative de la performance Java. Avant de changer le rapport initial et le maximum de tailles de tas, vous devez tenir compte des informations suivantes: Dans la majorité des cas, vous devez définir le nombre maximal de JVM de la taille du segment de valeur supérieure à la première taille de segment JVM. Cela permet à la JVM pour fonctionner efficacement pendant le fonctionnement normal de l'état d'équilibre des périodes dans l'enceinte de l'initiale du tas, mais aussi de fonctionner efficacement pendant les périodes de fort volume de transactions en élargissant le tas jusqu'à concurrence du maximum de la JVM de la taille du segment. Dans quelques cas rares où absolu de la performance optimale est nécessaire, vous pouvez spécifier la même valeur à la fois la formation initiale et taille maximale du tas. Cela permettra d'éliminer une surcharge se produit lorsque la JVM besoins pour développer ou réduire la taille du segment de la JVM. Assurez-vous que la région est assez grand pour contenir le spécifiée segment de la JVM. Méfiez-vous de la prise de la première Taille de Segment de mémoire trop importante. Alors qu'un grand tas de la taille d'abord améliore les performances en retardant la collecte des ordures, une grande taille de segment de mémoire affecte en fin de compte le temps de réponse lors de la collecte des ordures finalement en branle, parce que le processus de collecte prend plus de temps.

Donc, je crois que la raison pour laquelle vous ne pouvez pas modifier la valeur au moment de l'exécution est parce qu'il ne peut pas aider: soit vous avez assez d'espace dans votre tas ou vous n'avez pas. Une fois que vous exécutez un cycle de GC sera déclenchée. Si ce n'est pas de libérer de l'espace, vous êtes bourré de toute façon. Vous devrez capturer l'exception OutOfMemoryException, augmentation de la taille du tas, puis réessayer de vous calcul, en espérant que cette fois, vous avez assez de mémoire.

En général, la VM ne pas utiliser la taille maximale du tas, sauf si vous en avez besoin, si vous pensez que vous pourriez avoir besoin d'étendre la mémoire lors de l'exécution, vous pouvez simplement spécifier une grande taille maximale du tas.

J'avoue que tout est un peu décevant, et il semble un peu paresseux, puisque je ne peux imaginer une raisonnable de collecte des ordures stratégie qui permettrait d'augmenter la taille de segment de mémoire lors de la GC ne parvient pas à libérer suffisamment d'espace. Si mon imagination se traduit par une haute performance de la GC de la mise en œuvre est une autre affaire bien ;)

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