web-dev-qa-db-fra.com

Perm espace vs espace de tas

Premièrement, quelle est la différence entre l’espace Perm et l’espace Heap (Que et comment la JVM choisit-elle d’utiliser chaque espace mémoire)?

Deuxièmement, mais surtout, quel type de rapport serait recommandé pour une application Java standard de type MVC?

76
Gareth

Heap stocke tous les objets créés par votre programme Java. Le contenu du segment est surveillé par le ramasse-miettes, ce qui libère de la mémoire du segment lorsque vous arrêtez d'utiliser un objet (c'est-à-dire lorsqu'il n'y a plus de références à l'objet.

Ceci est en contraste avec le stack, qui stocke les types primitifs tels que ints et chars, qui sont généralement des variables locales et des valeurs de retour de fonction. Ce ne sont pas des ordures collectées.

L'espace perm fait référence à une partie spéciale du tas. Voir cette réponse SO pour une explication: Qu'est-ce que l'espace perm?

76
Olhovsky

Personnellement, je ne considérerais pas PermGen comme une partie spéciale du tas. 

Je préférerais de beaucoup penser à heap comme une zone mémoire dédiée à stocker des instances d'objet, tandis que PermGen comme une zone dédiée à stocker les définitions de classe. En conséquence, le cycle de vie d'un segment de mémoire est lié à une application, tandis que le cycle de vie de PermGen est lié à une machine virtuelle Java. 

L'un des meilleurs exemples pour lesquels une application et sa machine virtuelle Java peuvent avoir un cycle de vie différent réside dans un conteneur Java EE. Dans un serveur d'applications, les applications peuvent être déployées et non déployées sans redémarrer le serveur. Pendant le déploiement (ou le redéploiement), il est facile de libérer toutes les instances d'objet, c'est-à-dire un espace réduit, mais il est plutôt délicat d'effacer toutes les classes chargées par cette application depuis PermGen car certaines classes peuvent toujours être référencées par la JVM.

L'un de ces cas est le Fuite Pilotes . Lorsqu'une application est déployée, un pilote JDBC est chargé et enregistré auprès de DriverManager. Lorsque cette application n'est pas déployée, DriverManager reste allumé et contient une référence au pilote, à son chargeur de classe d'origine et à tout ce que ce chargeur de classe a chargé. En conséquence, une fuite de mémoire dans PermGen est créée, mais la gestion de la mémoire de l'application n'est pas imputable.

Il est vrai que les machines virtuelles telles que JRocket n’ont pas du tout de PermGen, tout est stocké dans le tas. Ce n'est que dans un tel contexte que vous pouvez appeler PermGen une "partie spéciale" du tas. Même dans ce cas, nous devrions toujours voir PermGen et heap différemment car ils ont des objectifs très différents et des types de fuites de mémoire très différents.

Update: dans le JDK 8 d'Oracle, PermGen est remplacé par "Metaspace" et fait maintenant officiellement partie du tas. Nous n'aurons plus besoin d'ajuster spécifiquement PermGen.

33
Christopher Yang

Vous ne pouvez PAS donner de noms à la mémoire allouée dans le tas. 

Cela signifie que int x (son nom) est alloué dans la pile. Vous pouvez atteindre le pointeur par son nom, de sorte qu'il se trouve dans la pile. Vous ne pouvez pas atteindre l'objet par son nom, car il n'a pas de nom. L'accès à l'objet (sans nom) doit être par son pointeur.

0
Pete Del Fina