Куча против стека против пермского пространства - PullRequest
36 голосов
/ 23 июля 2011
  • В чем различия между областями памяти Java (пространство Пермь, стек, куча)?
  • Когда JVM использует то или другое?
  • Если я использую Scala / Groovy / и т. Д., Есть ли различия?

Ответы [ 2 ]

81 голосов
/ 23 июля 2011

Просто

  • Пространство кучи: все живые объекты размещены здесь.
  • Пространство стека: хранит ссылки на объект для переменной в вызове метода или создании переменной.
  • Пермское пространство: хранит информацию о загруженных классах

Например:

Student std = new Student();

после выполнения строки над состоянием памяти будет выглядеть следующим образом.

  • Куча: магазины "new Student ()"
  • Stack: хранит информацию о "std"
  • Perm Space: хранит информацию о классе ученика
7 голосов
/ 10 сентября 2017

Простите за добавление ответа на такой старый вопрос - текущий ответ великолепен, но пропускает пару крайних случаев из-за статического кода и обновлений Java 8.

Обзор

  • Stack
    • Выделено на тему
    • Хранит локальные ссылки и примитивы
    • Это объем памяти - Когда метод или поток заканчивается, все их данные в стеке теряются
    • Имеет самый быстрый доступ, поэтому локальный примитив быстрее в использовании, чем локальный объект
  • Heap
    • Здесь есть все выделенные экземпляры объектов
    • Разделенный на поколения, первое место на котором смотрит GC
    • Доступно для всех потоков, поэтому распределения и освобождения должны быть синхронизированы
    • Эта память может стать фрагментированной (, но вы обычно сами не управляете этим )
  • PermGen
    • Хранит загруженную информацию о классе
    • Хранит неизменную информацию (Приматы, интернированные строки)
    • Хранит статический класс членов

Пример кода

public class SimpleVal { //The Class (loaded by a classloader) is in the PermGen

    private static final int MAGIC_CONSTANT = 42; //Static fields are stored in PermGen
    private static final SimpleVal INSTANCE = new SimpleVal(1); //Static field objects are created in the heap normally, with the reference in the PermGen ('class statics' moved to the heap from Java 7+)
    private static SimpleVal previousInstance; //Mutable static fields also have their reference in PermGen so they can easily cause memory leaks

    private int value; //Member variables will be part of the heap

    public SimpleVal(int realValue) {
        value = realValue;
        ...
    }

    public static int subtract(SimpleVal val1, SimpleVal val2) {
         ....
    }

    public int add(SimpleVal other) { //Only one copy of any method (static or not) exists - in PermGen
         int sum = value + other.value; //Local values in methods are placed in the Stack memory
         return sum;
    }

}

public static void main(String[] args) {

    SimpleVal val1 = null;
    SimpleVal val2 = new SimpleVal(3); //Both of these variables (references) are stored in the Stack 

    val1 = new SimpleVal(14); //The actual objects we create and add to the variables are placed in the Heap (app global memory, initially in the Young Gen space and later moved to old generation, unless they are very large they can immediately go old gen)

    int prim = val1.add(val2); //primitive value is stored directly in the Stack memory
    Integer boxed = new Integer(prim); //but the boxed object will be in the heap (with a reference (variable) in the Stack)

    String message = "The output is: "; //In Java 7+ the string is created in the heap, in 6 and below it is created in the PermGen
    System.out.println(message + prim);

}

Java 8 Примечание: Пространство PermGen было заменено на то, что называется Metaspace. Это все еще работает так же, но может быть изменено автоматически - по умолчанию Metaspace auto увеличивает свой размер в собственной памяти до максимума (указанного в параметрах JVM), но PermGen всегда имеет фиксированный максимальный размер, смежный с кучей памяти.

Примечание для Android: Начиная с Android 4.0 (из практики 3.0) Android должен соблюдать описанные контракты с памятью, но в более старых версиях реализация была нарушена . Память «Stack» в Android-Davlik фактически основана на регистре (размеры команд и их количество различаются, но для разработчика функциональность остается неизменной).

Наконец, для получения дополнительной информации, лучший ответ, который я когда-либо видел на эту тему в StackOverflow: здесь

...