Где размещена ссылка на переменную, в стеке или в куче? - PullRequest
11 голосов
/ 17 мая 2009

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

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

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

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

Я думаю, что в стеке, но я запутался, потому что я читал в книге J2ME Game Programming «Классы Java создаются в куче Java»

Все ява класы?

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

Ответы [ 4 ]

24 голосов
/ 17 мая 2009

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

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

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

13 голосов
/ 17 мая 2009

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

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

6 голосов
/ 17 мая 2009

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

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

3 голосов
/ 17 мая 2009

Условно объект отправляется в «кучу». Тогда, поскольку это локальная ссылка на метод, фактическая ссылка будет в стеке. Под стеком «мы» подразумевается стек собственных потоков (т. Е. Тот же стек, на котором будет размещаться локальная переменная в C), по крайней мере, в случае виртуальной машины Sun. просто нужно иметь какое-то абстрактное понятие «стековые фреймы», которые оно выделяет при каждом вызове метода, будь то из собственного стека или нет).

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

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

...