web-dev-qa-db-fra.com

Un tableau Java de primitives est-il stocké dans une pile ou un tas?

J'ai une déclaration de tableau comme celle-ci:

int a[];

Ici a est un tableau de type primitif int. Où est stocké ce tableau? Est-il stocké sur un tas ou une pile? Il s'agit d'un type primitif int, tous les types primitifs ne sont pas stockés sur le tas.

81
user241924

Comme l'a dit Gurukulki, il est stocké sur le tas. Cependant, votre message a suggéré un malentendu probablement dû à une personne bien intentionnée propageant le mythe selon lequel "les primitifs vivent toujours sur la pile". C'est faux. Variables locales ont leurs valeurs sur la pile, mais toutes les variables primitives ne sont pas locales ...

Par exemple, considérez ceci:

public class Foo
{
    int value;
}
...

public void someOtherMethod()
{
    Foo f = new Foo();
    ...
}

Maintenant, où va f.value vivre? Le mythe suggère qu'il se trouve sur la pile - mais en fait, il fait partie du nouvel objet Foo et vit sur le tas1. (Notez que la valeur de f elle-même est une référence et vit sur la pile.)

De là, c'est une étape facile pour les tableaux. Vous pouvez considérer un tableau comme étant simplement un grand nombre de variables - donc new int[3], c'est un peu comme avoir une classe de cette forme:

public class ArrayInt3
{
    public readonly int length = 3;
    public int value0;
    public int value1;
    public int value2;
}

1 En fait, c'est plus compliqué que ça. La distinction pile/tas est principalement un détail d'implémentation - je pense que certaines machines virtuelles Java, peut-être expérimentales, peuvent dire quand un objet ne "s'échappe" jamais d'une méthode, et peuvent allouer l'objet entier sur la pile. Cependant, c'est conceptuellement sur le tas, si vous choisissez de vous en soucier.

143
Jon Skeet

Il sera stocké sur le tas

parce que le tableau est un objet en Java.

MODIFIER : si vous avez

int [] testScores; 
testScores = new int[4];

Considérez ce code comme disant au compilateur: "Créez un objet tableau qui contiendra quatre pouces et affectez-le à la variable de référence nommée testScores. De plus, allez-y et définissez chaque élément int à zéro. Merci. "

36
GuruKulki

Il s'agit d'un tableau de types primitifs qui en soi n'est pas primitif. Une bonne règle est que lorsque le nouveau mot clé est impliqué, le résultat sera sur le tas.

20
Esben Skov Pedersen

Je voulais juste partager quelques tests que j'ai effectués sur ce sujet.

Tableau de taille 10 millions

public static void main(String[] args) {
    memInfo();
    double a[] = new double[10000000];
    memInfo();
}

Sortie:

------------------------
max mem = 130.0 MB
total mem = 85.0 MB
free mem = 83.6 MB
used mem = 1.4 MB
------------------------
------------------------
max mem = 130.0 MB
total mem = 130.0 MB
free mem = 48.9 MB
used mem = 81.1 MB
------------------------

Comme vous le voyez, la taille de tas utilisée est augmentée de ~ 80 Mo, ce qui correspond à 10m * sizeof (double).

Mais si nous avons utilisé Double au lieu de double

public static void main(String[] args) {
    memInfo();
    Double a[] = new Double[10000000];
    memInfo();
}

La sortie affichera 40 Mo. Nous n'avons que des références doubles, elles ne sont pas initialisées.

Remplir avec Double

public static void main(String[] args) {
    memInfo();
    Double a[] = new Double[10000000];      
    Double qq = 3.1d;
    for (int i = 0; i < a.length; i++) {
        a[i] = qq;
    }
    memInfo();
}

Toujours 40 Mo. Parce qu'ils pointent tous vers le même objet Double.

Initialisation avec double à la place

public static void main(String[] args) {
    memInfo();
    Double a[] = new Double[10000000];
    Double qq = 3.1d;
    for (int i = 0; i < a.length; i++) {
        a[i] = qq.doubleValue();
    }
    memInfo();
}

Exception in thread "main" Java.lang.OutOfMemoryError: Java heap space

Ligne

a[i] = qq.doubleValue();

est équivalent à

a[i] = Double.valueOf(qq.doubleValue());

ce qui équivaut à

a[i] = new Double(qq.doubleValue());

Puisque nous créons à chaque fois de nouveaux objets Double, nous soufflons le tas. Cela montre que les valeurs à l'intérieur de la classe Double sont stockées dans le tas.

15
acheron55

Dans le Java tableaux de langage de programmation sont des objets, sont créés dynamiquement et peuvent être affectés à des variables de type objet.

http://Java.Sun.com/docs/books/jls/second_edition/html/arrays.doc.html

2
Nikola Gedelovski