Где находится ссылка на переменную, в стеке или в куче?

У меня есть вопрос

Что происходит, когда я объявляю переменную внутри метода, например.

void myMethod() {
    Ship myShip = new Ship();
}

Где указано ссылка myShip, в стеке или в куче?

Я думаю, что в стеке, но я в замешательстве, потому что читал в J2ME Game Programming book "Java-классы создаются на кучу Java"

Все java-кланы?

Заранее спасибо

Ответ 1

myShip является ссылкой на объект Ship, myShip находится в стеке вызовов метода, который называется "стек". Когда метод называется блоком памяти, толкается вверху стека, этот блок памяти имеет место для всех примитивов (int, float, boolean и т.д.) И ссылки на объекты метода, который включает в себя параметры метода. Куча - это место, где выделяется память для реальных объектов.

Итак, myShip находится в стеке, а объект Ship находится в куче.

Обратите внимание, что каждый поток имеет свой собственный стек, но разделяет кучу.

Ответ 2

Java действительно делает что-то по-другому. Ссылка в основном на стек. Память для объекта выделяется в том, что проходит для кучи. Однако реализация распределяемой памяти не совсем похожа на то, как куча реализована в модели C/С++.

Когда вы создаете новый объект, подобный этому, он эффективно помещает это имя в таблицу ссылок для этой области. Это похоже на указатель на объект на С++. Когда он выходит из сферы действия, эта ссылка теряется; выделенная память больше не ссылается и может быть собрана в мусор.

Ответ 3

В настоящее время все объекты Java выделяются в куче. Есть разговоры о том, что Java 7 может выполнить анализ эвакуации и иметь возможность выделять в стеке, но я не знаю, завершено ли это предложение. Здесь RFE.

Изменить: По-видимому, он уже в ранних версиях JDK 7. (В статье говорится, что он также будет в JDK 6u14, но я не могу найти подтверждение.)

Ответ 4

Понятно, что объект переходит в "кучу". Затем, поскольку это локальная ссылка метода, фактическая ссылка будет находиться в стеке. Под "стеком" мы подразумеваем стек нативного потока (то есть тот же стек, на который будет распределяться локальная переменная в C) в случае Sun VM по крайней мере, но я не думаю, что на самом деле это требование (JVM просто нужно иметь какое-то абстрактное понятие о "кадрах стека", которое оно выделяет при каждом вызове метода, будь то из собственного стека или нет).

Но... на современных виртуальных машинах (по общему признанию, возможном исключении из простых встроенных /mpbile виртуальных машин) действительно нет такой вещи, как "куча". На практике существуют различные области кучи. Самый простой из них, как правило, почти как "мини-стек", предназначенный для быстрого выделения для объектов, которые долго не будут болтаться и, вероятно, могут быть де-распределены почти сразу.

Как упоминалось еще одним плакатом, высоко оптимизированная JVM могла в принципе распределять объектные данные в стеке, и для этого есть определенные предложения. Хотя, как упоминалось в одной из ссылок, критика в этом заключается в том, что быстрая "eden" куча почти как стек (просто не "стек" ).