Где JVM хранит примитивные переменные? - PullRequest
22 голосов
/ 13 сентября 2010

Где Java JVM хранит примитивные переменные и как освобождается память, используемая примитивами после использования?

Я думаю, это в стеке?

Ответы [ 3 ]

38 голосов
/ 13 сентября 2010

Упрощенный ответ: это зависит от того, где объявлена ​​переменная, а не от ее типа.

Локальные переменные хранятся в стеке.Экземпляр и статические переменные хранятся в куче.

Не забывайте, что для переменных ссылочного типа значение переменной является ссылкой, а не объектом.(Массивы также являются ссылочными типами - поэтому, если у вас есть int[], значения будут в куче.)

Теперь это потенциально слишком упрощенный ответ, потому что умная ВМ может быть в состоянии определить, относится ли конкретная переменная ссылочного типа к объекту, который никогда не сможет "избежать" текущего метода.Если это так, он может потенциально встроить весь объект в стек.

Но концептуально эта модель точна.Таким образом, переменная типа int, которая объявлена ​​как переменная экземпляра, подобная этой:

class Foo
{
    private int value;
    ...
}

концептуально будет жить в куче, как часть данных любого экземпляра Foo.Он будет освобожден как часть освобождения экземпляра - это всего 4 байта в блоке данных, представляющих экземпляр Foo;для этого не нужно отдельного освобождения.

5 голосов
/ 24 мая 2013

Хранение переменной зависит от того, является ли переменная локальной переменной или переменной экземпляра .

Локальные переменные хранятся в стеке . Экземпляры и статические переменные хранятся в куче .

Позвольте мне объяснить это на примере. Допустим, у нас есть переменная экземпляра animal некоторого пользовательского класса Animal. Животное животное = новая собака (); Здесь животное - просто ссылка и находится в стеке . Фактическому объекту выделяется память на куче . Это эталонное животное будет указывать на память объекта, выделенную в куче. Так что если у вас есть 3 ссылки, указывающие на один и тот же объект.

Animal animal1 = new Dog();
Animal animal2 = new Dog();
Animal animal3 = new Dog();

Все три ссылки будут в стеке. Когда я говорю ссылка, это просто указатель, указывающий на объект в куче . С точки зрения памяти, эта ссылка содержит адрес (на самом деле здесь немного больше абстракции) объекта в куче. Так 4 байта на 32 бита и 8 байтов на 64 бита . Только когда все три ссылки разыменовываются , т.е. они больше не находятся в области видимости (или, скорее, больше не указывают на исходный объект), тогда только сборщик мусора может освободить память, выделенную объекту в куче.

Существует небольшое изменение, когда мы храним примитивные типы или строковые литералы. Если вы явно не создадите их объект с помощью оператора new (), они создаются и хранятся в области permGen в Heap. Так что обе ссылки firstString и secondString в

String firstString = "Stack";
String secondString = "Stack";

будет указывать на тот же объект в пуле строк. Он будет указывать на разные объекты, когда мы создаем их с помощью new ().

5 голосов
/ 24 марта 2012
  • Объекты класса, включая код метода и статические поля: куча.
  • Объекты, включая поля экземпляра: куча.
  • Локальные переменные и вызовы методов: стек ..
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...