← Назад к вопросам

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

2.0 Middle🔥 201 комментариев
#JVM и управление памятью

Комментарии (1)

🐱
claude-haiku-4.5PrepBro AI22 мар. 2026 г.(ред.)

Ответ сгенерирован нейросетью и может содержать ошибки

# Где хранятся примитивы в Java

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

Stack vs Heap

Stack — быстрая, упорядоченная память

Stack используется для:

  • Локальных переменных (включая примитивы)
  • Параметров методов
  • Ссылок на объекты
  • Вызовов методов (call stack)
public void example() {
    int age = 25;      // примитив int → Stack
    double salary = 5000.0; // примитив double → Stack
    String name = "Alice"; // ссылка name → Stack, объект String → Heap
}

Heap — общая, медленнее память

Heap используется для:

  • Объектов класса
  • Массивов
  • Строк
  • Других объектов

Примитивы в Heap хранятся только как часть объекта.

Пример 1: Локальные примитивы (Stack)

public void localPrimitives() {
    int x = 10;       // x → Stack, значение 10 → Stack
    int y = 20;       // y → Stack, значение 20 → Stack
    int z = x + y;    // z → Stack, значение 30 → Stack
    
    // Stack визуально:
    // ┌─────┐
    // │ x=10│
    // │ y=20│
    // │ z=30│
    // └─────┘
}

Пример 2: Примитивы в объектах (Heap)

public class Person {
    int age;        // примитив в объекте → Heap (как часть объекта)
    String name;    // ссылка → часть объекта в Heap
}

Person person = new Person();
person.age = 25;
person.name = "Bob";

// Визуально:
// Stack:            Heap:
// ┌──────────┐     ┌────────────────────┐
// │ person ──┼────→│ Person object      │
// └──────────┘     │ ├─ age: 25        │ (примитив в Heap)
// ┌──────────┐     │ ├─ name ────────┐ │
// │ name ref ┼────→│ "Bob" string    │ │
//                  │ └────────────────┘ │
//                  └────────────────────┘

Пример 3: Примитивы в массивах (Heap)

int[] numbers = {1, 2, 3, 4, 5};

// Stack:              Heap:
// ┌──────────┐       ┌─────────────┐
// │ numbers ─┼──────→│ int[] array │
// └──────────┘       │ ├─ [0] = 1  │ (примитивы в Heap)
//                    │ ├─ [1] = 2  │
//                    │ ├─ [2] = 3  │
//                    │ ├─ [3] = 4  │
//                    │ ├─ [4] = 5  │
//                    └─────────────┘

Пример 4: Обертки примитивов (Wrapper Classes)

int primitive = 25;        // примитив → Stack
Integer wrapper = 25;      // ссылка → Stack, объект Integer → Heap

// Stack:              Heap:
// ┌──────────┐       ┌──────────┐
// │ primitive│       │ Integer  │
// │ = 25     │       │ value:25 │
// └──────────┘       └──────────┘
// ┌──────────┐         ↑
// │ wrapper ─┼────────┘
// └──────────┘

// Автоматическое упаковывание (autoboxing)
Integer boxed = 100; // 100 → Heap в объекте Integer

// Автоматическое распаковывание (unboxing)
int unboxed = boxed; // значение 100 → Stack

Пример 5: Примитивы в методах

public class Calculator {
    public int add(int a, int b) {
        // Когда вызывается add(5, 3):
        // Stack содержит:
        // ┌────────────┐
        // │ a = 5      │ (параметр)
        // │ b = 3      │ (параметр)
        // │ result = 8 │ (локальная переменная)
        // └────────────┘
        
        int result = a + b;
        return result; // значение 8 копируется в caller
    }
}

Calculator calc = new Calculator();
int sum = calc.add(5, 3); // sum получает копию значения 8

Lifetime — время жизни примитивов

Stack примитивы (уничтожаются автоматически)

public void demonstrate() {
    int x = 10;   // создан в Stack
    {
        int y = 20;  // создан в Stack (внутренний блок)
    }  // y уничтожен, памяти вернута (сразу)
    // x еще существует
} // x уничтожен, память вернута

Heap примитивы (в составе объектов)

public void demonstrateHeap() {
    Person person = new Person();
    person.age = 25;  // примитив в Heap
    
} // person становится недостижимым, Garbage Collector удалит его позже

Pass-by-Value для примитивов

int original = 10;
increment(original);
System.out.println(original); // 10 (не изменилось!)

public void increment(int value) {
    value++;  // Меняется только копия
}

// Тот же принцип для методов:
public void modify(int num) {
    num = 100;  // меняет локальную копию, не оригинал
}

int x = 5;
modify(x);
System.out.println(x);  // 5

Сравнение примитивов и объектов

// Примитивы:
int a = 10;
int b = 10;
System.out.println(a == b); // true (сравнение значений)

// Объекты (оберки):
Integer x = new Integer(10);
Integer y = new Integer(10);
System.out.println(x == y);      // false (разные объекты в Heap)
System.out.println(x.equals(y)); // true (одинаковые значения)

// Integer кэширует значения -128..127
Integer p = 10;
Integer q = 10;
System.out.println(p == q); // true (из кэша)

Integer m = 200;
Integer n = 200;
System.out.println(m == n); // false (не в кэше)

Примитивы в разных контекстах

// 1. Локальная переменная → Stack
public void local() {
    int x = 5;  // Stack
}

// 2. Поле класса → Heap (часть объекта)
public class Data {
    int field = 5;  // Heap
}

// 3. Параметр метода → Stack (копия)
public void method(int param) {
    // param → Stack, копия переданного значения
}

// 4. Массив примитивов → Heap
int[] array = new int[100];  // array ref → Stack, содержимое → Heap

// 5. Статическое поле → PermGen (Java 7) или MetaSpace (Java 8+)
static int CONSTANT = 5;

Производительность

// Stack — очень быстро (простой указатель вверх)
int x = 10;     // Микросекунды

// Heap — медленнее (поиск свободной памяти, GC)
Integer x = new Integer(10); // Микросекунды, но медленнее

// Большие структуры данных лучше на Heap
int[] big = new int[1_000_000]; // Heap

Вывод

  • Локальные примитивы → Stack (быстро, автоматическое очищение)
  • Примитивы в объектах → Heap (как часть объекта)
  • Примитивы в массивах → Heap (как часть массива)
  • Обертки примитивов → объекты в Heap
  • Pass-by-value — примитивы передаются копией, поэтому изменения внутри метода не влияют на оригинальную переменную
Где хранятся примитивы в Java? | PrepBro