2010-09-05 20 views
49

Je sais juste que les non-primitives (les objets) vont sur le tas, et les méthodes vont sur la pile, mais qu'en est-il des variables primitives?Les primitives Java vont-elles sur la pile ou le tas?

--update

Sur la base des réponses, je pourrais dire le tas peut avoir une nouvelle pile et tas pour un objet donné? Étant donné que l'objet aura des variables primitives et de référence ..?

+1

Chaque thread a sa propre pile, pas chaque objet. S'il n'y a qu'un seul thread, alors il n'y a qu'une seule pile. – Alex

Répondre

77

Les primitives définies localement seraient sur la pile. Cependant, si une primitive était définie comme faisant partie d'une instance d'un objet, cette primitive serait sur le tas.

public class Test 
{ 
    private static class HeapClass 
    { 
     public int y; // When an instance of HeapClass is allocated, this will be on the heap. 
    } 
    public static void main(String[] args) 
    { 
     int x=1; // This is on the stack. 
    } 
} 

En ce qui concerne la mise à jour:

Les objets ne possèdent pas leur propre pile. Dans mon exemple, int y ferait réellement partie de chaque instance de HeapClass. Chaque fois qu'une instance de HeapClass est allouée (par exemple new HeapClass()), toutes les variables membres de HeapClass sont ajoutées au tas. Ainsi, puisque des instances de HeapClass sont allouées sur le tas, int y serait sur le tas dans le cadre d'une instance de HeapClass. Cependant, toutes les variables primitives déclarées dans le corps de n'importe quelle méthode seraient sur la pile.

Comme vous pouvez le voir dans l'exemple ci-dessus, int x est sur la pile car il est déclaré dans un corps de méthode - et non en tant que membre d'une classe.

+0

+1 Merci! S'il vous plaît, considérez ma nouvelle mise à jour à la question. –

+1

Vous pourriez vouloir modifier le commentaire dans votre code. Dans le texte, vous dites que 'x' est sur la pile mais le commentaire dit tas. – musiKk

+0

Bonne prise. Merci. –

19

Toutes les variables locales (y compris les arguments de méthode) vont sur la pile; les objets et tous leurs champs sont stockés dans le tas. Les variables sont toujours des primitives ou références aux objets.

Les implémentations Java peuvent effectivement stocker des objets sur le tas de manière à ce qu'il soit toujours conforme à la spécification. De même, les variables locales peuvent être stockées dans des registres ou devenir indistinctes grâce à l'optimisation.

+0

+1 Merci! S'il vous plaît, considérez ma nouvelle mise à jour à la question. –

10

Des primitives peuvent être trouvées aux deux endroits.

class Foo 
{ 
    public int x; 
    public static void Main() 
    { 
     int y = 3; // y is on the stack 
     Foo f = new Foo(); // f.x is probably on the heap 
    } 
} 

sauf que vous ne devriez pas vous en soucier à moins de construire une JVM. Un optimiseur très astucieux peut décider que depuis le Foo pointant f ne s'échappe jamais de Main, et n'est jamais passé à une autre fonction qu'il est sûr de l'allouer sur la pile.

En ce qui concerne la mise à jour:

La pile et le tas ne sont pas distingués par ce qui est stocké en eux, mais plutôt les opérations prévues pour eux. La pile vous permet d'allouer un morceau de mémoire de façon LIFO, vous ne pouvez pas libérer un morceau tant que toutes les pièces plus jeunes n'ont pas été désaffectées. Cela correspond parfaitement à la façon dont une pile d'appels est utilisée. Vous pouvez mettre n'importe quoi sur la pile tant qu'il est bon que cette chose disparaisse quand votre fonction retourne. Ceci est une optimisation, car il est très rapide à allouer et à désallouer d'une pile car il ne supporte que d'être utilisé de cette manière. On pourrait stocker toutes les variables locales pour une fonction sur le tas dans une implémentation si on le voulait. Le tas est plus flexible, et par conséquent plus coûteux à utiliser. Il ne serait pas exact de dire qu'un objet a une pile et un tas, comme je l'ai dit, ce qui distingue la pile du tas n'est pas ce qui s'y trouve, mais les opérations disponibles.

+0

+1 Merci! S'il vous plaît, considérez ma nouvelle mise à jour à la question. –

+0

@Logan: '// f.x est probablement sur le tas >> -> Voulez-vous dire que cela dépend de l'implémentation de la JVM? – realPK

7

valeurs primitives sont allouées sur la pile à moins que ce sont des champs d'un objet, auquel cas ils vont sur le tas. La pile est utilisée pour l'évaluation et l'exécution, donc il n'est pas logique de dire que les objets avec des champs primitifs ont une pile - il est toujours considéré comme faisant partie du tas. Même les objets Stack sont alloués sur le tas.