У меня есть такое объявление массива:
int a[];
Вот a
массив примитивного int
типа. Где хранится этот массив? Он хранится в куче или стеке? Это примитивный тип int
, все примитивные типы не хранятся в куче.
У меня есть такое объявление массива:
int a[];
Вот a
массив примитивного int
типа. Где хранится этот массив? Он хранится в куче или стеке? Это примитивный тип int
, все примитивные типы не хранятся в куче.
Ответы:
Как сказал гурукулки, хранится в куче. Тем не менее, ваш пост предполагает недоразумение, вероятно, из-за некоего благонамеренного человека, распространяющего миф о том, что «примитивы всегда живут в стеке». Это неправда. Локальные переменные имеют свои значения в стеке, но не все примитивные переменные являются локальными ...
Например, рассмотрим это:
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, возможно, экспериментальные, могут определить, когда объект никогда не «ускользнет» из метода, и могут выделить весь объект в стеке. Однако концептуально это в куче, если вы решите позаботиться.
String
них поддерживается файлом char[]
. Я считаю, что буквальные строки хранятся в общедоступном пуле констант; для оптимизации сборщика мусора это будет означать, что резервные массивы должны храниться аналогичным образом (в противном случае постоянный пул должен быть сканирован во время любого цикла сборщика мусора, где резервный массив в противном случае имел бы право на сбор).
Он будет храниться в куче
потому что массив - это объект в java.
РЕДАКТИРОВАТЬ : если у вас есть
int [] testScores;
testScores = new int[4];
Думайте об этом коде как о сообщении компилятору: «Создайте объект массива, который будет содержать четыре целых числа, и назначьте его ссылочной переменной с именем testScores
. Кроме того, продолжайте и установите каждый int
элемент в ноль. Спасибо».
-g
опцию компилятору. В противном случае он будет оптимизирован.
Это массив примитивных типов, который сам по себе не является примитивным. Хорошее практическое правило заключается в том, что при использовании ключевого слова new результат будет в куче.
Я просто хотел поделиться несколькими тестами, которые я провел на эту тему.
Массив размером 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.
Инициализация с помощью 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
Линия
a[i] = qq.doubleValue();
эквивалентно
a[i] = Double.valueOf(qq.doubleValue());
что эквивалентно
a[i] = new Double(qq.doubleValue());
Поскольку мы каждый раз создаем новые объекты Double, мы сдуваем кучу. Это показывает, что значения внутри класса Double хранятся в куче.
В языке программирования Java массивы являются объектами, создаются динамически и могут быть присвоены переменным типа Object.
http://java.sun.com/docs/books/jls/second_edition/html/arrays.doc.html