Почему следующий массив помещается в кучу, а не в стек в Java
Я недавно узнал, что объекты могут быть помещены в стек или в кучу, и место их размещения определяется путем анализа побега. ( Объявление нескольких массивов с 64 элементами в 1000 раз быстрее, чем объявление массива из 65 элементов)
В следующем примере я думаю, что объект "test" помещается в кучу, что значительно увеличивает время выполнения:
public static void main(String args[]) {
double start = System.nanoTime();
long job = 100000000;// 100 million
int total = 0;
for (long i = 0; i < job; i++) {
int j = 0;
double[] test = new double[63];
test[0] =1;
total += test[0];
while (true) {
if (j == 0)
break;
j--;
}
test[0] = 10; // this makes a really big difference
}
double end = System.nanoTime();
System.out.println("Total runtime = " + (end - start) / 1000000 + " ms" + " total ="+ total);
}
Если либо цикл while удален, либо "test[0] = 10;" В данном случае объектный тест помещается в стек (я получил это из того факта, что сборщик мусора в этом случае не вызывается, тогда как это происходит, когда присутствуют оба. Кроме того, время выполнения составляет 350 мс вместо 6803 мс).
У меня вопрос, почему объектный тест помещается в кучу, если я изменяю / обращаюсь к содержимому объекта после цикла while?
2 ответа
test
является локальной ссылочной переменной для вашего основного метода. Все локальные переменные хранятся в стеке. Вот изображение, которое поможет вам понять, что происходит в куче, а что в стеке:
Также время выполнения составляет 350 мс вместо 6803 мс
Я думаю, что речь идет не о стеке / куче, а об оптимизации. Я не уверен, как именно работает JIT-оптимизация Java, но похожий код на C/C++ после оптимизации будет выглядеть так:
public static void main(String args[]) {
double start = System.nanoTime();
long job = 100000000;// 100 million
int total = 100000000;
double end = System.nanoTime();
System.out.println("Total runtime = " + (end - start) / 1000000 + " ms" + " total ="+ total);
}
может быть, если вы ссылаетесь на тест:
test[0]=10;
это приводит к тому, что цикл for не может быть "удален"