Может ли Java выделить список в стеке?

Каждый раз, когда я инициирую список в java, я буду делать

List<Integer> list = new LinkedList<>();

Я предполагаю, что это будет размещать список в куче. Интересно, есть ли способ разместить список в стеке?


person user2640480    schedule 24.04.2014    source источник
comment
Почему вы хотите, чтобы он размещался в стеке?   -  person Puce    schedule 24.04.2014
comment
Это чисто академическое?   -  person wvdz    schedule 24.04.2014
comment
@LuiggiMendoza PermGen не был памятью стека. Именно здесь были выделены классы и другие структуры, которые, как ожидается, будут существовать до конца процесса JVM; перемещение их в отдельное пространство сделало сборку мусора в обычной куче более эффективной. По мере того как разгрузка классов становилась все более рутинной, этот выигрыш в эффективности становился менее очевидным.   -  person erickson    schedule 24.04.2014
comment
list находится в стеке, однако это ссылка, а фактические объекты находятся в куче.   -  person Peter Lawrey    schedule 24.04.2014
comment
@PeterLawrey, но только если это локальная переменная. Если это переменная-член, она также будет в куче.   -  person Puce    schedule 24.04.2014
comment
Теоретически @Puce анализ побега может выполнять уклонение от объекта, и поля-члены также будут в стеке. На практике такого почти никогда не бывает.   -  person Peter Lawrey    schedule 24.04.2014


Ответы (2)


Все объекты, включая их индивидуальные атрибуты, хранятся в куче.

Все локальные переменные и их аргументы хранятся в стеке, поскольку они содержат примитивные значения или ссылки.

Однако в особых случаях виртуальная машина Java может выполнить анализ побега и принять решение о размещении объектов (включая ваш LinkedList) в стеке, но обычно этого не происходит и это не является серьезной проблемой.

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

person manan    schedule 24.04.2014
comment
Тогда как насчет С++? Похоже, C++ может разместить список в стеке, выполнив list‹int› a;. И тогда он может выполнять любую желаемую операцию. - person user2640480; 24.04.2014
comment
@user2640480 user2640480 Это помещает в стек только первый/корневой объект, остальные узлы должны быть в куче. - person Peter Lawrey; 24.04.2014
comment
@user264080 user264080 как правило, если вы выделяете объект в стеке, вы получите копию объекта при вызове функции, которая ссылается на него, но если вы выделяете его в куче, когда вы передаете указатель на объект вы получите копию указателя (указывающего на тот же самый объект в куче). - person manan; 24.04.2014
comment
Таким образом, даже в C++, я думаю, я не могу вернуть объект (выделенный в стеке) по мере возврата функции, потому что он будет всплывать вместе со стеком. Это правильно? - person user2640480; 24.04.2014
comment
Когда распределение выполняется в стеке, относится ли это к стеку JVM или к стеку C/C++, используемому для локальных переменных C/C++? - person nanofarad; 19.08.2016

Теоретически реализации JVM могут размещать объекты в стеке, используя «анализ побега». Если можно определить, что ссылка на созданный объект никогда не утекает из стека, JVM может разместить ее в стеке, а не в куче. Преимущество этого будет заключаться в уменьшении накладных расходов на сборку мусора; при выходе из кадра стека эта память может быть немедленно освобождена. Это также может повысить скорость из-за локальности ссылки.

Начиная с Java 7, escape-анализ был представлен в среде выполнения Oracle HotSpot Java. Благодаря этому усовершенствованию HotSpot может не выделять локальные объекты стека, которые не были изменены; вместо того, чтобы размещать их в стеке, он полностью удаляет выделение. Хотя это не соответствует выделению стека, это демонстрирует, что такие вещи являются допустимыми оптимизациями во время выполнения.

Однако Java-программист не может напрямую управлять этим поведением. Это оптимизация, выполняемая JIT-компилятором. Я не уверен, что спецификация языка разрешает такую ​​оптимизацию во время компиляции. Может быть, но я не изучал.

person erickson    schedule 24.04.2014
comment
Насколько я знаю, EscapeAnalysis появляется в Java 6 версии 17. Существует < href="https://stackoverflow.com/a/43002529/548473">подробное исследование состояния - person Grigory Kislin; 27.12.2018