Де зберігаються статичні методи та статичні змінні на Java?


115

Наприклад:

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
дуже корисне посилання, щоб зрозуміти збирання сміття на офіційному веб-сайті Oracle: oracle.com/webfolder/technetwork/tutorials/obe/java/gc01/…
Joshi

Відповіді:


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()як це не гарантовано працювати. Спільне вирішення питання про те, коли запустити сміттєзбірник і що збирати, залежить, навіть якщо об'єкт має право на вивезення сміття.

Звичайно , ви можете встановити змінну статичного в нуль і , таким чином , видалити посилання на об'єкт в купі , але це не означає , що збирач сміття буде збирати його (навіть якщо немає більше посилань).

Додатково finalize()запускається лише один раз, тому ви повинні переконатися, що він не викидає винятки або іншим чином перешкоджає збиранню об'єкта. Якщо ви зупините фіналізацію через якийсь виняток, finalize()вдруге не буде викликано один і той же об’єкт.

Остаточне зауваження : як зберігаються код, дані часу виконання тощо, залежить від використовуваного JVM, тобто HotSpot може робити це інакше, ніж JRockit, і це може відрізнятися між версіями одного JVM. Вищенаведене базується на HotSpot для Java 5 та 6 (вони в основному однакові), оскільки під час відповіді я б сказав, що більшість людей використовували ці JVM. Зважаючи на значні зміни в моделі пам'яті, що стосується Java 8, наведені вище твердження можуть бути неправдивими для Java 8 HotSpot - і я не перевіряв зміни Java 7 HotSpot, тому, мабуть, вищезазначене все-таки справедливо для цієї версії, але я тут не впевнений.


1
Ах, ти впевнений у статичних змінних? AFAIK PermGen зберігає лише визначення, а не фактичне значення.
Амір Рамінфар

2
@Amir Я майже впевнений, що сама змінна зберігається в пермгенському просторі, будь-який посилається об'єкт, швидше за все, буде виділений на купі. Сюди можна додати трохи інформації: stackoverflow.com/questions/3800444/…
Томас

1
Так, змінне визначення зберігається в permgen. Але значення буде в купі. Ваша відповідь підказує, що значення також зберігається в PermGen.
Амір Рамінфар

1
@Matthew, як ти розумієш мою відповідь? Казав, що змінні зберігаються в розділі permgen (примітиви / посилання), а не об'єкти, на які вони посилаються. Це залежить від того, як ви переглядаєте значення змінних .
Томас

1
@Nav не всі частини купи зібрані за замовчуванням, а іноді й класи, тому статичні змінні неможливо збирати, оскільки завантажувачі класів все ще мають посилання на них. Крім того, ви не повинні покладатися на роботу сміттєзбірника, оскільки це повністю залежить від JVM (він вирішує, коли запускати і що збирати, ви можете лише надати підказки типу "Я хотів би, щоб ви запустили gc зараз" :)) .
Томас

25

Змінні класу (Статичні змінні) зберігаються як частина Class objectасоційованого з цим класом. Цей об'єкт Class може бути створений тільки JVM і зберігається в permanent generation.

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

Ще один спосіб це побачити

Пули пам'яті створюються менеджерами пам'яті JVM під час виконання. Пул пам’яті може належати або купі, або пам'яті, що не купує. Постійний пул часу виконання - це представлення таблиці часу_бігу в таблиці класів для кожного класу або за інтерфейсом. Кожен постійний пул часу виконання виділяється з області методу віртуальної машини Java, а статичні змінні зберігаються в цій області методів. Крім того, ця негромадна ділянка - це не що інше, як область пермського роду. Фактично область методу є частиною генеалогічної категорії ( довідник )

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


область методу не є підмножиною розділу PermGen пам'яті? Чому ви показали область методу як частину негромової пам'яті, коли, я думаю, вони (PermGen разом із областю методу (класу)) є частиною більшої маси кути JVM?
Kaveesh Kanwal

Прочитайте останній рядок -Also this non-heap is nothing but perm gen area.Actually Method area is part of perm gen.
Анікет Такур

1
@AniketThakur ви показали область методу як частину негромової пам'яті, але згідно з документами Oracle, тут, docs.oracle.com/javase/specs/jvms/se7/html/… , згадується, що область методу логічно входить до купи.
Каран

21

До Java 8:

Статичні змінні зберігалися в пермгенному просторі (також його називають областю методу).

Простір PermGen також відомий як «Область методів»

PermGen Space використовується для зберігання 3 речей

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

Від Java 8 і далі

Статичні змінні зберігаються в самій Heap. З Java 8 далі було видалено простір PermGen і введено новий простір, названий як MetaSpace, який вже не є частиною Heap на відміну від попереднього Permgen Space. Мета-простір присутній у вбудованій пам'яті (пам'ять, яку ОС надає певній програмі для власного використання) і тепер зберігає лише метадані класу.

Інтерновані рядки та статичні змінні переміщуються в саму купу.

Для офіційної інформації дивіться: JEP 122: Видаліть простір постійного генератора


коли ви говорите "купа самі" для статичних змінних> Java8, де саме: OldGen?
Ewoks

15

Це запитання з простою відповіддю і довготривалою відповіддю.

Проста відповідь - це купа. Класи та всі дані, що застосовуються до класів (не дані про екземпляри), зберігаються у розділі "Постійне покоління" у купі.

Довга відповідь вже переповнюється стеком:

Існує ретельний опис пам’яті та збирання сміття в JVM , а також відповідь, яка говорить про це більш стисло .


3
Звісна річ! Не забудьте просити цих хлопців, якщо ви вважаєте їх корисними.
Василь Шарапов

11

Він зберігається в купі, на яку посилається визначення класу. Якщо ви подумаєте про це, це не має нічого спільного зі стеком, оскільки немає сфери застосування.


5

На додаток до відповіді Томаса, статична змінна зберігається в області, що не купується, і називається Метод Площа.


4

Оскільки статичні змінні є змінними рівня класу, вони зберігатимуть " постійне покоління " купи пам'яті. Будь ласка, перегляньте це для більш детальної інформації про JVM. Сподіваючись, що це буде корисним


3

статичні змінні зберігаються в купі


7
Статична змінна зберігається в просторі PremGen в пам'яті, їх значення зберігаються в Heap.
Акаш5288
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.