2009-05-17 6 views
11

J'ai une questionOù est attribué la référence de la variable, dans la pile ou dans le tas?

Que se passe-t-il lorsque je déclare une variable dans une méthode, par exemple.

 
void myMethod() { 
    Ship myShip = new Ship(); 
} 

Où se trouve la référence myShip allouée, en pile ou dans le tas?

Je pense que dans la pile mais je suis confus parce que je lisais dans le livre de la programmation de jeux J2ME « classes Java sont instanciés sur le tas Java »

Tous les clases java?

Merci d'avance

+0

Cette question est un peu peu claire telle quelle. Cela pourrait être soit "Où est la référence à myShip stockée en mémoire?" ou "Où l'objet pointé par myShip est-il stocké en mémoire?" La réponse conceptuelle à la première est la pile, et la réponse conceptuelle à cette dernière est le tas, à l'exception des optimisations et des implémentations folles, et il y a des réponses qui y répondent dans les deux sens. –

Répondre

23

myShip est une référence à un objet Ship, myShip est sur la pile d'appel de méthode, qui est appelée "la pile". Quand une méthode est appelée un bloc de mémoire est poussée en haut de la pile, ce bloc de mémoire a de l'espace pour toutes les primitives (int, float, boolean etc.) et des références d'objet de la méthode, qui inclut les paramètres de la méthode. Le tas est l'endroit où la mémoire pour les objets réels est allouée.

Donc myShip est sur la pile et l'objet Ship est sur le tas. Notez que chaque thread a sa propre pile mais partage le tas.

13

Java fait vraiment les choses un peu différemment. La référence est essentiellement sur la pile. La mémoire de l'objet est allouée dans ce qui passe pour le tas. Cependant, l'implémentation de la mémoire allouable n'est pas tout à fait comme la façon dont le tas est implémenté dans le modèle C/C++. Lorsque vous créez un nouvel objet comme celui-ci, il place effectivement le nom dans la table de références pour cette étendue. C'est un peu comme un pointeur vers un objet en C++. Quand il sort du champ d'application, cette référence est perdue; la mémoire allouée n'est plus référencée et peut être récupérée par la mémoire.

+0

Que se passe-t-il s'il s'agit simplement d'un 'Ship ship'? Cela signifie que la référence du bateau est sur la pile, mais qu'aucun objet n'est créé. Mais cela signifie-t-il que la classe 'Ship' est chargée à ce stade? – Joeblackdev

+0

Vraiment? J'ai pensé que faire cela crée une référence de vaisseau initialisée avec null. Y a-t-il une différence? – Joeblackdev

+3

@CharlieMartin: Vous avez tort, Ship ship; ne construisez pas un navire! La variable est juste initialisée à null. – tibo

6

Actuellement, tous les objets Java sont alloués sur le tas. Il est question que Java 7 pourrait échapper à l'analyse et être capable d'allouer sur la pile, mais je ne sais pas si la proposition est encore finalisée. Here's the RFE.

Édition: Apparemment, c'est already in early builds of JDK 7. (L'article dit qu'il sera également dans JDK 6u14, mais je ne trouve pas de confirmation.)

+2

L'analyse d'échappement n'affecte pas la sémantique du code, cependant, on ne devrait jamais avoir besoin de compter sur ou d'assumer son existence. – bdonlan

+2

@bdonlan: Correct, cependant l'analyse d'échappement (implémentée depuis Java SE 6u23, btw) contribue à ce que le Java d'aujourd'hui ne soit pas le canard boiteux qu'il était il y a 15 ans. –

3

Notionellement, l'objet passe sur "le tas". Puis, parce que c'est une référence méthode-locale, la référence réelle sera sur la pile. Par "la" pile, nous entendons la pile de threads natifs (c'est-à-dire la même pile qu'une variable locale dans C) dans le cas de VM de Sun au moins, mais je ne pense pas que ce soit une exigence (la JVM Il suffit d'avoir une notion abstraite de "cadres de pile" qu'il alloue à chaque appel de méthode, que ce soit à partir de la pile native ou non.

Mais ... sur les machines virtuelles modernes (avec peut-être l'exception possible des machines virtuelles incorporées/mpbile plus simples), il n'y a vraiment rien de tel que le segment de mémoire "the". En pratique, il existe plusieurs zones de tas. La plus simple d'entre elles est typiquement presque une "mini-pile", conçue pour être rapidement allouée aux objets qui ne traînent pas longtemps et qui peuvent probablement être désaffectés presque immédiatement.

Comme mentionné par une autre affiche, une JVM hautement optimisée pourrait allouer en principe des données d'objet sur la pile et il y a des propositions précises pour cela. Bien que, comme mentionné également dans l'une des références, une critique de ceci est que le tas rapide "eden" est presque comme une pile de toute façon (juste pas "la" pile).

Questions connexes