Где статические методы и статические переменные хранятся в Java?

116

Например:

class A {
    static int i=0;
    static int j;

   static void method() {
       // static k=0; can't use static for local variables only final is permitted
       // static int L;
    }
}

Где эти переменные будут храниться в Java, в куче или в стековой памяти? Как они хранятся?

навигационный
источник
2
очень полезная ссылка для понимания
сборки

Ответы:

144

Статические методы (фактически все методы), а также статические переменные хранятся в PermGenразделе кучи, поскольку они являются частью данных отражения (данные, относящиеся к классу, а не к экземплярам).

Обновление для уточнения :

Обратите внимание, что в пространстве PermGen хранятся только переменные и их технические значения (примитивы или ссылки).

Если ваша статическая переменная является ссылкой на объект, сам объект хранится в обычных разделах кучи (молодое / старое поколение или пространство оставшихся в живых). Эти объекты (если они не являются внутренними объектами, такими как классы и т. Д.) Не хранятся в пространстве PermGen.

Пример:

static int i = 1; //the value 1 is stored in the PermGen section
static Object o = new SomeObject(); //the reference(pointer/memory address) is stored in the PermGen section, the object itself is not.


Несколько слов о сборке мусора:

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

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

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

Последнее замечание : способ хранения кода, данных времени выполнения и т. Д. Зависит от используемой JVM, т.е. HotSpot может делать это иначе, чем JRockit, и это может даже отличаться между версиями одной и той же JVM. Вышеупомянутое основано на HotSpot для Java 5 и 6 (они в основном одинаковы), поскольку на момент ответа я бы сказал, что большинство людей использовали эти JVM. Из-за значительных изменений в модели памяти, начиная с Java 8, приведенные выше утверждения могут быть неверными для Java 8 HotSpot - и я не проверял изменения Java 7 HotSpot, поэтому я предполагаю, что вышесказанное по-прежнему верно для этой версии, но я здесь не уверен.

Томас
источник
1
Вы уверены в статических переменных? AFAIK PermGen хранит только определения, а не фактическое значение.
Амир Раминфар 05
2
@Amir Я почти уверен, что сама переменная хранится в пространстве permgen, любой объект, на который имеется ссылка, скорее всего, будет размещен в куче. Это может добавить некоторую информацию: stackoverflow.com/questions/3800444/…
Thomas
1
Ах да, определение переменной хранится в permgen. Но значение будет в куче. Ваш ответ предполагает, что значение также хранится в PermGen.
Амир Раминфар 05
1
@ Мэтью, как ты понял мой ответ? A сказал, что переменные хранятся в разделе permgen (примитивы / ссылки), а не объекты, на которые они ссылаются. Это зависит от того, как вы видите значение переменных .
Thomas
1
@Nav не все части кучи собираются мусором по умолчанию, а иногда и классы, и поэтому статические переменные не могут быть собраны, поскольку загрузчики классов все еще имеют ссылку на них. Кроме того, вы не должны полагаться на запуск сборщика мусора, поскольку это полностью зависит от JVM (он решает, когда запускать и что собирать, вы можете предоставлять только подсказки типа «Я бы хотел, чтобы вы запустили gc сейчас» :)) .
Thomas
25

Переменные класса (статические переменные) хранятся как часть Class objectсвязанных с этим классом. Этот объект класса может быть создан только JVM и хранится в permanent generation.

Также некоторые ответили, что он хранится в области без кучи, которая называется. Method Area.Даже этот ответ не является неправильным. Является ли Пермский участок частью кучи - это спорный вопрос. Очевидно, что восприятие различается от человека к человеку. На мой взгляд, мы по-разному предоставляем пространство кучи и пространство для перманента в аргументах JVM. Так что относиться к ним по-другому - хорошее предположение.

Другой способ увидеть это

Пулы памяти создаются менеджерами памяти JVM во время выполнения. Пул памяти может принадлежать памяти кучи или не кучи. Пул констант времени выполнения - это представление времени выполнения для каждого класса или интерфейса таблицы constant_pool в файле класса. Каждый пул констант времени выполнения выделяется из области методов виртуальной машины Java, а статические переменные хранятся в этой области методов. Кроме того, эта не-куча является не чем иным, как перманентной областью. Фактически, это часть перманентной области. ( Ссылка )

введите описание изображения здесь

Аникет Такур
источник
область метода не является подмножеством раздела памяти PermGen? Почему вы показали область метода как часть памяти без кучи, когда, я думаю, они (PermGen вместе с областью метода (класса)) являются частью большей области кучи JVM?
Кавиш Канвал
Прочтите последнюю строчку -Also this non-heap is nothing but perm gen area.Actually Method area is part of perm gen.
Аникет Такур
1
@AniketThakur вы показали область метода как часть памяти без кучи, но, согласно документам оракула, здесь, docs.oracle.com/javase/specs/jvms/se7/html/… , упоминается, что область метода логически является частью куча.
Karan
21

До Java 8:

Статические переменные хранились в перманентном пространстве (также называемом областью метода).

PermGen Space также известен как Область метода

PermGen Space использовался для хранения 3 вещей

  1. Данные уровня класса (метаданные)
  2. интернированные строки
  3. статические переменные

Начиная с Java 8

Статические переменные хранятся в самой куче. Начиная с Java 8 пространство PermGen было удалено и введено новое пространство с именем MetaSpace, которое больше не является частью кучи, в отличие от предыдущего пространства Permgen. Мета-пространство присутствует в собственной памяти (память, предоставляемая ОС конкретному приложению для собственного использования), и теперь в нем хранятся только метаданные класса.

Интернированные строки и статические переменные перемещаются в саму кучу.

Официальная информация: JEP 122: Удалить постоянное пространство генерации.

Маниш Кумар
источник
когда вы говорите «сама куча» для статических переменных> Java8, где именно: OldGen?
Ewoks
15

Это вопрос с простым ответом и развернутым ответом.

Ответ простой - куча. Классы и все данные, применяемые к классам (не данные экземпляра), хранятся в разделе постоянной генерации кучи.

Длинный ответ уже о переполнении стека:

Существует подробное описание памяти и сборки мусора в JVM, а также ответ, который говорит об этом более кратко .

Василий Шарапов
источник
3
Конечно! Не забудьте проголосовать за этих ребят, если они вам пригодятся.
Василий Шарапов
11

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

Амир Раминфар
источник
5

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

Vipin
источник
4

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

Рамеш Папаганти
источник
3

статические переменные хранятся в куче

ЦБС
источник
7
Статические переменные хранятся в пространстве PremGen в памяти, их значения хранятся в Heap.
Akash5288