Jak dzielona jest pula pamięci Java?


224

Obecnie monitoruję aplikację Java za pomocą jconsole. Karta pamięci pozwala wybrać między:

Heap Memory Usage
Non-Heap Memory Usage
Memory Pool “Eden Space”
Memory Pool “Survivor Space”
Memory Pool “Tenured Gen”
Memory Pool “Code Cache”
Memory Pool “Perm Gen”

Jaka jest różnica między nimi ?


Zakładając, że używasz Sun JDK, najlepszą odpowiedzią będzie można znaleźć w ich dokumentacji: Tuning Garbage Collection (JDK 1.5) i Garbage Collection FAQ (JDK 1.4)
kdgregory

Odpowiedzi:


327

Pamięć stert

Pamięć sterty jest obszarem danych wykonawczych, z którego maszyna wirtualna Java przydziela pamięć dla wszystkich instancji klas i tablic. Sterty mogą mieć stały lub zmienny rozmiar. Garbage collector to automatyczny system zarządzania pamięcią, który odzyskuje pamięć sterty dla obiektów.

  • Eden Space : pula, z której początkowo przydzielana jest pamięć dla większości obiektów.

  • Survivor Space : kałuża zawierająca przedmioty, które przetrwały zbiór śmieci w przestrzeni Eden.

  • Tenured Generation lub Old Gen : pula zawierająca obiekty, które istniały przez pewien czas w przestrzeni ocalałych.

Pamięć bez stosu

Pamięć bez stosu obejmuje obszar metody współużytkowany przez wszystkie wątki i pamięć wymaganą do wewnętrznego przetwarzania lub optymalizacji maszyny wirtualnej Java. Przechowuje struktury dla poszczególnych klas, takie jak pula stałych środowiska wykonawczego, dane pól i metod oraz kod metod i konstruktorów. Obszar metody jest logicznie częścią sterty, ale w zależności od implementacji wirtualna maszyna Java nie może go wyrzucać do pamięci ani go kompaktować. Podobnie jak pamięć sterty, obszar metody może mieć stały lub zmienny rozmiar. Pamięć obszaru metody nie musi być ciągła.

  • Permanent Generation : pula zawierająca wszystkie dane odblaskowe samej maszyny wirtualnej, takie jak obiekty klasy i metody. W przypadku maszyn wirtualnych Java, które korzystają z udostępniania danych klasy, ta generacja jest podzielona na obszary tylko do odczytu i do odczytu i zapisu.

  • Pamięć podręczna kodu : maszyna wirtualna Java HotSpot zawiera również pamięć podręczną kodu, zawierającą pamięć używaną do kompilacji i przechowywania natywnego kodu.

Oto dokumentacja na temat korzystania z Jconsole .


4
Nie jestem pewien, czy @dfa jest całkowicie poprawne, ponieważ specyfikacja wirtualnej maszyny Java wyraźnie stwierdza: „Chociaż obszar metody jest logicznie częścią sterty, proste implementacje mogą zdecydować, aby nie zbierać elementów bezużytecznych lub je kompaktować”. Jednak jasne jest, że jconsole pokazuje pamięć podręczną kodu i generowanie ciągłe jako non-sterty, co wydaje się być sprzeczne ze specyfikacją. Czy ktoś może wyjaśnić tę sprzeczność?
James Bloom

@JamesBloom - zastanawiałem się nad tym samym. Mimo że podstawowa definicja określa, do której puli pamięci należy dany typ (sterty / bez sterty), to może ona zmienić jawnie stan?
Umang Desai,

2
dokument ten został przypuszczalnie podszyty z: docs.intergral.com/pages/viewpage.action?pageId=22478944 Dokument zawiera kilka innych dobrych informacji o JVM, wartych przejrzenia
Steve Siebert

1
Pomimo wielu pozytywnych opinii, w rzeczywistości nie jest to tak znacząca odpowiedź. Na przykład, co oznacza „obiekty, które przetrwały zbiórkę śmieci w przestrzeni Eden”? Czy po przeżyciu te obiekty są przenoszone z kosmosu do Strefy Ocalałych, czy też ich przestrzeń w Edenie jest uważana za przestrzeń Ocalałych? A co z śmieciowaniem w basenach innych niż przestrzeń Eden, czy to się dzieje? Zupełnie niejasne.
Michaił Batcer

i nie zapomnij o stosie (po stronie bez stosu) :)
Toothless Seer

70

Nowe słowo kluczowe przydziela pamięć na stercie Java. Sterta jest główną pulą pamięci, dostępną dla całej aplikacji. Jeśli nie ma wystarczającej ilości pamięci do przydzielenia dla tego obiektu, JVM próbuje odzyskać część pamięci ze sterty przy użyciu funkcji wyrzucania elementów bezużytecznych. Jeśli nadal nie można uzyskać wystarczającej ilości pamięci, zgłaszany jest błąd OutOfMemoryError i JVM kończy pracę.

Kupa jest podzielona na kilka różnych sekcji, zwanych pokoleniami. Ponieważ obiekty przeżywają więcej śmieci, są one promowane do różnych generacji. Starsze pokolenia nie są tak często zbierane. Ponieważ przedmioty te okazały się już dłużej żywe, rzadziej są one zbierane w śmieciach.

Kiedy obiekty są budowane po raz pierwszy, są one przydzielane w przestrzeni Eden. Jeśli przeżyją zbiórkę śmieci, awansują do Przestrzeni Ocalałych, a jeśli tam żyją wystarczająco długo, zostają przydzieleni do Generacji Wytrzymałości. To pokolenie śmieci są zbierane znacznie rzadziej.

Istnieje również czwarta generacja, zwana Permanent Generation lub PermGen. Obiekty znajdujące się tutaj nie kwalifikują się do odśmiecania i zwykle zawierają niezmienny stan niezbędny do uruchomienia JVM, taki jak definicje klas i pula stała String. Zauważ, że przestrzeń PermGen jest planowana do usunięcia z Java 8 i zostanie zastąpiona nową przestrzenią o nazwie Metaspace, która będzie przechowywana w pamięci natywnej. odniesienie :http://www.programcreek.com/2013/04/jvm-run-time-data-areas/

wprowadź opis zdjęcia tutaj wprowadź opis zdjęcia tutaj


Schemat wygląda bardzo intuicyjnie ... Czy dotyczy to dowolnego algorytmu GC. G1 mają inny zestaw.
Venkateswara Rao,

@Pythoner Myślę, że flaga w kolorze ciemnofioletowym powinna być, -XX:PermSizea nie -XX:MaxPermSizejak już zdefiniowano powyżej.
Anurag


23

Java Heap Memory jest częścią pamięci przydzielonej JVM przez system operacyjny.

Obiekty znajdują się w obszarze zwanym stertą. Sterta jest tworzona podczas uruchamiania JVM i może zwiększać lub zmniejszać rozmiar podczas działania aplikacji. Kiedy sterty zostaną zapełnione, śmieci są zbierane.

wprowadź opis zdjęcia tutaj

Więcej informacji na temat Eden Space, Survivor Space, Tenured Space i Permanent Generation znajduje się w poniższym pytaniu SE:

Generacja młodych, pełnoletnich i stałych

PermGen został zastąpiony Metaspace od wydania Java 8.

Odnośnie twoich zapytań:

  1. Eden Space, Survivor Space, Tenured Space są częścią pamięci stosu
  2. Metaspace i Cache Cache są częścią pamięci nie-sterty.

Codecache: Java Virtual Machine (JVM) generuje kod macierzysty i przechowuje go w obszarze pamięci zwanym codecache. JVM generuje kod macierzysty z różnych powodów, w tym dla dynamicznie generowanej pętli interpretera, kodów pośredniczących Java Native Interface (JNI) oraz metod Java, które są kompilowane do kodu macierzystego przez kompilator just-in-time (JIT). JIT jest zdecydowanie największym użytkownikiem pamięci podręcznej.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.