Почему следующий массив помещается в кучу, а не в стек в 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 не может быть "удален"

Другие вопросы по тегам