Массив Java примитивов хранится в стеке или куче? - PullRequest
81 голосов
/ 20 января 2010

У меня есть объявление массива, подобное этому:

int a[];

Здесь a - массив примитивного типа int. Где хранится этот массив? Хранится ли он в куче или в стеке? Это тип примитива int, все типы примитивов не хранятся в куче.

Ответы [ 5 ]

144 голосов
/ 20 января 2010

Как сказал гурукульки, он хранится в куче.Тем не менее, ваш пост предположил недопонимание, вероятно, из-за благих намерений человека, распространяющего миф о том, что «примитивы всегда живут в стеке».Это неправда. Локальные переменные имеют свои значения в стеке, но не все примитивные переменные являются локальными ...

Например, рассмотрим это:

public class Foo
{
    int value;
}
...

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

Теперь, где жеf.value жить?Миф предполагает, что он находится в стеке, но на самом деле он является частью нового объекта Foo и живет в куче 1 .(Обратите внимание, что значение f само по себе является ссылкой и находится в стеке.)

Отсюда легко перейти к массивам.Вы можете думать о массиве как о множестве переменных - так что new int[3] немного походит на класс этой формы:

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

1 На самом делеСложнее, чем это.Различие стека / кучи - это в основном детали реализации - я полагаю, что некоторые JVM, возможно, экспериментальные, могут сказать, когда объект никогда не «выходит» из метода, и могут выделить весь объект в стеке.Тем не менее, это концептуально в куче, если вы решите заботиться.

36 голосов
/ 20 января 2010

Он будет сохранен в куче

, поскольку массив является объектом в Java.

EDIT : если у вас есть

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

Думайте об этом коде как о том, что он говорит компилятору: "Создайте объект массива, который будет содержать четыре целых числа, и присвойте его ссылочной переменной с именем testScores. Кроме того, продолжайте и установите каждый элемент intв ноль. Спасибо. "

20 голосов
/ 20 января 2010

Это массив примитивных типов, который сам по себе не является примитивным. Хорошее практическое правило - когда задействовано новое ключевое слово, результат будет в куче.

15 голосов
/ 02 мая 2013

Я просто хотел поделиться несколькими тестами по этому предмету.

Массив размером 10 миллионов

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

Выход:

------------------------
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
------------------------

Как видите, размер используемой кучи увеличивается на ~ 80 МБ, что составляет 10 м * sizeof (double).

Но если мы используем Double вместо double

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

Вывод покажет 40 МБ. У нас есть только двойные ссылки, они не инициализированы.

Заполнение двойным

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();
}

Все еще 40 МБ. Потому что все они указывают на один и тот же объект 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.doubleValue();
    }
    memInfo();
}

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

Line

a[i] = qq.doubleValue();

эквивалентно

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

, что эквивалентно

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

Поскольку мы каждый раз создаем новые двойные объекты, мы выбрасываем кучу. Это показывает, что значения внутри класса Double хранятся в куче.

2 голосов
/ 20 января 2010

В языке программирования Java массивы являются объектами, создаются динамически и могут быть назначены переменным типа Object.

http://java.sun.com/docs/books/jls/second_edition/html/arrays.doc.html

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...