Может ли объект храниться в стеке вместо кучи в java?

Может ли объект храниться в стеке вместо кучи?

Недавно я прошел через этот блог http://www.programmerinterview.com/index.php/data-structures/difference-between-stack-and-heap/

Может ли объект храниться в стеке вместо кучи?

Да, объект может быть сохранен в стеке. Если вы создаете объект внутри функции без использования "нового" оператора, тогда это создаст и сохранит объект в стеке, а не в куче. Предположим, у нас есть класс С++, называемый Member, для которого мы хотим создать объект. У нас также есть функция, называемая некоторой функцией(). Вот как выглядит код:

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

Я думал, что

  • Все объекты в Java хранятся в куче.
    создается ли она с помощью а. new Keyword
    б. Использование Class.forName().
    с. Использование clone().
    д. Использование метода newInstance()
    е. Использование десериализации объектов.

  • Способы, потоки и переменные находятся в стеке.

  • Переменные класса (статические переменные) сохраняются как часть объекта класса, связанного с этим классом. Этот объект класса может быть создан только JVM и хранится в постоянном поколении.

Пожалуйста, поправьте меня, если я ошибаюсь.

Теперь я сомневаюсь, могут ли объекты находиться или храниться в стеке в любой форме.

Спасибо.

Ответ 1

Все экземпляры класса хранятся в куче.

Вот некоторые достоверные источники:
Из спецификации JVM:
https://docs.oracle.com/javase/specs/jvms/se8/jvms8.pdf

2.5.3 Heap

Виртуальная машина Java имеет кучу, которая используется для всех потоков виртуальной машины Java. Куча - область данных времени выполнения из которого выделяется память для всех экземпляров классов и массивов.

Из языка Java Spec:
https://docs.oracle.com/javase/specs/jls/se8/jls8.pdf

17.4.1 Общие переменные

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

Ответ 2

Ваша точка (1): все объекты выделены в куче.

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

Однако обратите внимание, что Oracle конкретно говорит, что он не заменяет распределение кучи на распределение стека в результате его анализа escape в этой технической заметке.

Итак, да, объекты всегда находятся в куче в (Oracle) Java.


Ваша точка (2): методы, потоки и переменные находятся в стеке.

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

Сами методы являются частью класса. Объекты Thread выделяются как любой другой объект, но сами потоки не являются данными и не выделяются, но для них выделяются стеки.


Ваша точка (3): Статические переменные выделяются в PermGen.

Эта информация верна вплоть до Java 8. Согласно JEP 122, они теперь выделены в куче, поскольку PermGen был удален.

Обратите внимание, что такие детали реализации различны между различными реализациями JVM. Другие JVM избавились от PermGen еще до Java 8.

Ответ 3

Все объекты Java должны быть выделены в куче:

JVMS 8 2.5.3:

[...] Куча - это область данных времени выполнения, из которой память для всех классов экземпляров и массивов выделяется

Однако из-за анализа утечки некоторые объекты могут быть оптимизированы для примитивных типов и сохранены в стеке. Они никогда не становятся объектами в таком случае, поэтому не нарушают правило.

Ответ 4

Прокомментированный вами комментарий относится к С++, который может хранить объекты в стеке. На Java вы не можете.