← Назад к вопросам
В какой области памяти хранятся статические поля
2.3 Middle🔥 201 комментариев
#JVM и управление памятью#Основы Java
Комментарии (1)
🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)
Ответ сгенерирован нейросетью и может содержать ошибки
# В какой области памяти хранятся статические поля
Статические поля в Java хранятся в MethodArea/Metaspace (в Java 8+) или PermGen (в Java 7 и раньше). Это область памяти, которая содержит информацию о классе и постоянно существует во время выполнения программы.
Структура памяти в Java
┌─────────────────────────────┐
│ Heap (Куча) │ ← Объекты экземпляров
│ (Управляется GC) │
└─────────────────────────────┘
┌─────────────────────────────┐
│ Stack (Стек) │ ← Локальные переменные, ссылки
│ (По одному для потока) │
└─────────────────────────────┘
┌─────────────────────────────┐
│ MethodArea/Metaspace │ ← Статические поля, методы, классы
│ (Общая для всех потоков) │
└─────────────────────────────┘
MethodArea в Java 8+
В Java 8 введена Metaspace — замена PermGen. Она находится в Off-Heap памяти (система, а не JVM).
public class Configuration {
// Статическое поле — хранится в Metaspace
public static final String APP_NAME = "MyApp";
public static final int MAX_USERS = 1000;
// Обычное поле — хранится в Heap
private String userName;
public static void main(String[] args) {
// Локальная переменная — хранится в Stack
int count = 0;
// Объект — хранится в Heap
Configuration config = new Configuration();
}
}
Визуализация хранения данных
MethodArea/Metaspace:
├── Класс Configuration
│ ├── METHOD appName = "MyApp" (статическое поле)
│ ├── METHOD MAX_USERS = 1000 (статическое поле)
│ ├── METHOD main() (метод)
│ └── METHOD ...
└── Класс OtherClass
└── ...
Heap:
├── Configuration instance #1
│ └── userName = "John" (экземплярное поле)
└── Configuration instance #2
└── userName = "Jane" (экземплярное поле)
Stack (Поток 1):
├── count = 0 (локальная переменная)
├── config = ссылка на объект в Heap
└── ...
Stack (Поток 2):
├── count = 5 (локальная переменная)
├── config = ссылка на объект в Heap
└── ...
Практический пример
public class MemoryAreas {
// СТАТИЧЕСКОЕ ПОЛЕ — Metaspace
private static String appName = "MyApplication";
// СТАТИЧЕСКОЕ ПОЛЕ — Metaspace
private static List<User> cache = new ArrayList<>();
// ЭКЗЕМПЛЯРНОЕ ПОЛЕ — Heap (в каждом объекте)
private String userName;
public static void main(String[] args) {
// ЛОКАЛЬНАЯ ПЕРЕМЕННАЯ — Stack
int count = 0;
// ОБЪЕКТ — Heap
MemoryAreas obj = new MemoryAreas();
// Доступ к статическому полю (Metaspace)
System.out.println(MemoryAreas.appName);
// Доступ к экземплярному полю (Heap)
obj.userName = "Alice";
}
}
Время жизни статических полей
public class Lifecycle {
public static int counter = 0;
public static void main(String[] args) {
// 1. Класс загружается в Metaspace при первом использовании
System.out.println(Lifecycle.counter); // 0
// 2. Статическое поле инициализируется один раз
Lifecycle.counter = 5;
// 3. Значение сохраняется в Metaspace до конца программы
System.out.println(Lifecycle.counter); // 5
// 4. Все потоки видят одно и то же значение
new Thread(() -> System.out.println(Lifecycle.counter)).start(); // 5
// 5. После завершения программы — освобождается вместе с Metaspace
}
}
Различия между типами данных
public class DataStorage {
// 1. СТАТИЧЕСКОЕ ПОЛЕ (Metaspace)
public static String appName = "MyApp";
// 2. СТАТИЧЕСКАЯ ПЕРЕМЕННАЯ В МЕТОДЕ (Stack при вызове)
public static void printName() {
String localName = appName; // Stack
System.out.println(localName);
}
// 3. ЭКЗЕМПЛЯРНОЕ ПОЛЕ (Heap)
private int userId;
// 4. ЭКЗЕМПЛЯРНАЯ ПЕРЕМЕННАЯ (Stack при вызове)
public void setUser(String name) {
String localUserName = name; // Stack
// Используется...
} // localUserName удаляется из Stack
}
// Тестирование:
public static void main(String[] args) {
// appName находится в Metaspace и существует постоянно
// obj находится в Heap
// id находится в Stack этого потока
DataStorage obj = new DataStorage();
int id = 1;
obj.setUser("Alice");
}
PermGen vs Metaspace
Java 7 и раньше (PermGen)
Heap:
├── Объекты приложения
└── ...
PermGen (часть Heap):
├── Классы
├── Методы
├── Статические поля
└── String Pool
Проблема: PermGen имела фиксированный размер → OutOfMemoryError
Java 8+ (Metaspace)
Heap:
├── Объекты приложения
└── ...
Metaspace (Native Memory):
├── Классы
├── Методы
├── Статические поля
└── String Pool
Преимущество: Metaspace использует системную память → без ограничений
Конфигурация памяти
# Для Java 7 и раньше (PermGen)
java -Xms1024m -Xmx1024m -XX:PermSize=256m -XX:MaxPermSize=512m MyApp
# Для Java 8+ (Metaspace)
java -Xms1024m -Xmx1024m -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=512m MyApp
Где хранится что
public class StorageExample {
public static void main(String[] args) {
// 1. Статический текст (не массив)
String staticText = "Hello";
// Содержимое "Hello" может быть в String Pool
// (часть Metaspace или Heap в зависимости от версии)
// 2. Статический массив объектов
static Integer[] staticArray = {1, 2, 3};
// Сам массив (structure) — в Metaspace
// Объекты Integer — в Heap
// Ссылка staticArray — в Metaspace
// 3. Статическая коллекция
static List<User> users = new ArrayList<>();
// Ссылка на List — в Metaspace
// Сам ArrayList объект — в Heap
// Элементы List — в Heap
}
}
Одна копия для всех потоков
public class SharedStatic {
private static int counter = 0;
public static void main(String[] args) {
// Все потоки видят ОДНО и то же значение в Metaspace
Thread t1 = new Thread(() -> {
counter++;
System.out.println("T1: " + counter);
});
Thread t2 = new Thread(() -> {
counter++;
System.out.println("T2: " + counter);
});
t1.start();
t2.start();
// Race condition! Нужна синхронизация
}
}
Итоговая таблица
| Тип данных | Область памяти | Время жизни | Количество | Видимость |
|---|---|---|---|---|
| Статическое поле | Metaspace | До конца программы | 1 на класс | Все потоки |
| Экземплярное поле | Heap | До удаления объекта GC | По числу объектов | Один объект |
| Локальная переменная | Stack | До конца метода | По числу вызовов | Один поток |
| Параметр метода | Stack | До конца метода | По числу вызовов | Один поток |
Ключевые моменты
- Статические поля — Metaspace (Java 8+) или PermGen (Java 7-)
- Metaspace находится в Off-Heap памяти (системная память)
- Одна копия статического поля для всего приложения
- Все потоки видят одно значение статического поля
- Метаданные классов также в Metaspace (методы, поля, классы)
- Статические поля инициализируются один раз при загрузке класса
- Память освобождается в конце программы