Sterta vs stos vs przestrzeń Perm

  • Jakie są różnice między przestrzeniami pamięci Java (przestrzenią Perm, przestrzenią stosu, przestrzenią stosu)?
  • kiedy JVM używa jednego czy drugiego?
  • Jeśli używam Scala / Groovy / etc., czy są różnice?
Author: Kowser, 2011-07-23

2 answers

Po Prostu

  • Heap space: wszystkie żywe obiekty są przydzielane tutaj.
  • Stack space: przechowuje odwołania do obiektu dla zmiennej w wywołaniu metody lub instancji zmiennej.
  • przestrzeń Perm: przechowuje załadowane informacje o klasach

Na przykład:

Student std = new Student();

Po wykonaniu powyższej linii stan pamięci będzie taki.

  • Heap: stores "new Student ()"
  • Stack: przechowuje informacje o " std "
  • przestrzeń Perm: przechowuje informacje o Klasa ucznia
 75
Author: Kowser,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-07-23 18:19:26

Wybacz, że dodałem odpowiedź na tak stare pytanie - obecna odpowiedź jest świetna, ale pomija kilka przypadków edge ze względu na statyczny kod i aktualizacje Javy 8.

Przegląd

  • stos
    • przydzielane na wątek
    • przechowuje lokalne odniesienia i prymitywy
    • Jest to pamięć skalowana - gdy metoda lub wątek się kończy, wszystkie ich dane w stosie są tracone]}
    • ma najszybszy dostęp, więc lokalny prymityw jest szybszy w użyciu niż lokalny Obiekt
    • wszystkie przypisane instancje obiektu istnieją tutaj
    • podzielone na pokolenia, z najmłodszym pokoleniem jest pierwsze miejsce GC wygląda
    • dostępne dla wszystkich wątków, więc alokacje i dealokacje powinny być zsynchronizowane
    • pamięć ta może zostać rozdrobniona ( ale zazwyczaj nie radzisz sobie z tym sam )
  • PermGen
    • przechowuje załadowane informacje o klasie
    • sklepy immutable information (Primatives, interned Strings)
    • przechowuje static class członkowie

Przykładowy Kod

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 Notatka: przestrzeń PermGen została zastąpiona przez tak zwaną Metaspace. To nadal działa tak samo, ale może być automatycznie zmieniane - domyślnie metaspace automatycznie zwiększa swój rozmiar w pamięci natywnej do maksimum (określonego w JVM params), ale PermGen zawsze ma stały maksymalny rozmiar przylegający do sterty pamięć.

Android Uwaga: od Androida 4.0 (od 3.0 w praktyce) Android powinien honorować opisane umowy pamięci - ale na starszych wersjach implementacja została złamana. Pamięć "stosu" w Androidzie-Davlik jest w rzeczywistości oparta na rejestrze (rozmiary i liczby instrukcji różnią się między nimi, ale dla programisty funkcjonalność pozostaje taka sama).

Wreszcie, aby uzyskać więcej informacji najlepszą odpowiedzią jaką kiedykolwiek widziałem na ten temat na StackOverflow jest tutaj

 5
Author: Nick Cardoso,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-09-09 21:43:04