Используются ли примитивы Java в стеке или куче? - программирование
Подтвердить что ты не робот

Используются ли примитивы Java в стеке или куче?

Я просто знаю, что не-примитивы (объекты) идут в кучу, а методы идут в стеке, но как насчет примитивных переменных?

- обновление

На основе ответов я могу сказать, что куча может иметь новый стек и кучу для данного объекта? Учитывая, что объект будет иметь примитивные и ссылочные переменные..?

4b9b3361

Ответ 1

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

public class Test
{
    private static class HeapClass
    {
        public int y; // When an instance of HeapClass is allocated, this will be on the heap.
    }
    public static void main(String[] args)
    {
        int x=1; // This is on the stack.
    }
}

Что касается обновления:

Объекты не имеют собственного стека. В моем примере int y фактически будет частью каждого экземпляра HeapClass. Всякий раз, когда выделяется экземпляр HeapClass (например, new HeapClass()), все переменные-члены HeapClass добавляются в кучу. Таким образом, поскольку экземпляры HeapClass выделяются в куче, int y будет находиться в куче как часть экземпляра HeapClass.

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

Как вы можете видеть в приведенном выше примере, int x находится в стеке, потому что он объявлен в теле метода - не как член класса.

Ответ 2

Все локальные переменные (включая аргументы метода) идут в стек; объекты и все их поля хранятся в куче. Переменные всегда являются примитивами или ссылками на объекты.

Java-реализации могут фактически хранить объекты в куче таким образом, чтобы они все еще соответствовали спецификации. Точно так же локальные переменные могут храниться в регистрах или становиться нечеткими с помощью оптимизации.

Ответ 3

примитивы можно найти в обоих местах.

class Foo
{
   public int x;
   public static void Main()
   {
      int y = 3; // y is on the stack
      Foo f = new Foo();  // f.x is probably on the heap
   } 
}

кроме вас не должно волноваться, если вы не создаете JVM. Действительно умный оптимизатор может решить, что, поскольку Foo, что f указывает на то, что никогда не выходит из Main и никогда не переходит к другой функции, можно безопасно выделить его в стеке.

Что касается обновления:

Стек и куча не отличаются тем, что хранится в них, а скорее операциями, предусмотренными для них. Стек позволяет вам выделить кусок памяти в режиме LIFO, вы не можете освободить кусок, пока все части моложе его не будут освобождены. Это удобно сочетается с тем, как используется стек вызовов. Вы можете поместить что-нибудь в стек, если это нормально, когда эта вещь возвращается, когда ваша функция возвращается. Это оптимизация, так как очень быстро выделять и освобождать из стека, поскольку она поддерживает только то, что используется таким образом. Можно было бы сохранить все локальные переменные для функции в куче в реализации, если захотите. Куча более гибкая и, следовательно, более дорогая в использовании. Неверно было бы сказать, что у объекта есть стек и куча, как я уже сказал, что отличает стек от кучи не то, что в нем, а доступные операции.

Ответ 4

Примитивные значения выделяются в стеке, если они не являются полями объекта, и в этом случае они идут в кучу. Стек используется для оценки и выполнения, поэтому нет смысла говорить, что объекты с примитивными полями имеют стек - он по-прежнему считается частью кучи. Даже объекты Stack выделяются в куче.