Я просто хотел поделиться несколькими тестами, которые я провел по этому вопросу.
массив размером 10000000
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 МБ, что 10m * SizeOf (двойной).
Но если мы используем двойной вместо двойного
public static void main(String[] args) {
memInfo();
Double a[] = new Double[10000000];
memInfo();
}
выход покажет 40MB. У нас есть только двойные ссылки, они не инициализированы.
Заполнение его с двойным
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();
}
Still 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
Линия
a[i] = qq.doubleValue();
эквивалентно
a[i] = Double.valueOf(qq.doubleValue());
что эквивалентно
a[i] = new Double(qq.doubleValue());
Поскольку мы каждый раз создаем новые объекты Double, мы продуваем кучу. Это показывает значения внутри класса Double, хранящиеся в куче.
Это не массив. Это ссылка на массив. Сама эта ссылка может быть сохранена в куче, если она является членом класса или объекта или в стеке, если это локальная переменная в методе. И примитивные типы могут быть сохранены в куче, если они являются членами класса или объекта. – UncleO