Jaka jest różnica między PermGen i Metaspace?

118

Aż do Java 7 istniał obszar w pamięci JVM o nazwie PermGen , w którym JVM zachowywał swoje klasy. W Javie 8 został usunięty i zastąpiony obszarem o nazwie Metaspace .

Jakie są najważniejsze różnice między PermGen i Metaspace?

Jedyną różnicą, jaką znam, jest to, że java.lang.OutOfMemoryError: PermGen spacenie można już wyrzucać, a parametr VM MaxPermSizejest ignorowany.

Kao
źródło
pierwszy wynik Google: infoq.com/articles/Java-PERMGEN-Removed
the8472
@ the8472 Tak, ale te (i wiele innych) wyników google opisują tylko mechanizm Metaspace, nie wspominając o dokładnych różnicach między tym a PermGen.
Kao

Odpowiedzi:

137

Główna różnica z punktu widzenia użytkownika - co moim zdaniem poprzednia odpowiedź nie podkreśla wystarczająco - polega na tym, że Metaspace domyślnie automatycznie zwiększa swój rozmiar (do tego, co zapewnia podstawowy system operacyjny), podczas gdy PermGen zawsze ma ustalony maksymalny rozmiar. Możesz ustawić stałe maksimum dla Metaspace z parametrami JVM, ale nie możesz ustawić automatycznego zwiększania PermGen.

W dużej mierze to po prostu zmiana nazwy. Kiedy wprowadzono PermGen, nie było wczytywania (od) Java EE ani klas dynamicznych, więc po załadowaniu klasy utknęła w pamięci do czasu wyłączenia maszyny JVM - stąd Trwałe Generowanie. Obecnie klasy mogą być ładowane i zwalniane w trakcie życia maszyny JVM, więc Metaspace ma większy sens w obszarze, w którym przechowywane są metadane.

Oba zawierają java.lang.Classinstancje i oba cierpią z powodu wycieków ClassLoader . Jedyną różnicą jest to, że przy domyślnych ustawieniach Metaspace trwa to dłużej, zanim zauważysz objawy (ponieważ automatycznie zwiększa się tak bardzo, jak to możliwe), tj. Po prostu odsuwasz problem dalej bez rozwiązywania go. OTOH Wyobrażam sobie, że efekt wyczerpania pamięci systemu operacyjnego może być poważniejszy niż zwykły brak JVM PermGen, więc nie jestem pewien, czy jest to znaczna poprawa.

Niezależnie od tego, czy używasz maszyny JVM z PermGen, czy z Metaspace, jeśli wykonujesz dynamiczne wyładowywanie klas, powinieneś podjąć środki zapobiegające wyciekom klas, na przykład używając mojej biblioteki ClassLoader Leak Prevention .

Mattias Jiderhamn
źródło
17
Ani Permgen, ani Metaspace nie zawierają instancji klasy Class. Zachowują tylko metainformacje o załadowanych klasach. Instancje klasy Class są przechowywane w regularnym stosie, podobnie jak wystąpienia innych klas.
Przeciętny Joe
Niezłe porównanie. Dzięki
Sandeep
1
Nawiasem mówiąc, OTOH oznacza „Z drugiej strony”
sofs1
43

Do widzenia, do widzenia PermGen, Hello Metaspace

PermGen został całkowicie usunięty.

Wyrzucanie elementów bezużytecznych w metaspace - Wyrzucanie elementów bezużytecznych martwych klas i modułów ładujących jest wyzwalane, gdy użycie metadanych klasy osiągnie MaxMetaspaceSize.

Przestrzeń, która Metadatabyła przetrzymywana, nie jest już ciągła do Java heap, metadatateraz została przeniesiona do pamięci natywnej do obszaru znanego jako Metaspace.

W prostych słowach ,

Ponieważ metadane klasy są przydzielane z pamięci natywnej, maksymalna dostępna przestrzeń to całkowita dostępna pamięć systemowa. W ten sposób nie będziesz już napotykać OOM errorsi możesz skończyć wylać się na przestrzeń wymiany.

Usunięcie PermGennie oznacza, że ​​zniknęły problemy z wyciekiem klas. Więc tak, nadal będziesz musiał monitorować swoje zużycie i odpowiednio planować, ponieważ wyciek skończyłby się zużyciem całej pamięci natywnej.

Kilka innych artykułów z analizą: Link1 , Link2 i this

Ankur Singhal
źródło
6
Zamiast MaxPermGen masz MaxMetaspaceSize, więc nie ma powodu, aby używał więcej lub mniej pamięci lub masz mniejszą kontrolę.
Peter Lawrey
2
o jakiej pamięci tu mówimy? Pamięć RAM lub pamięć HDD.
Dinesh
1
@Dinesh RAM (pamięć wewnętrzna)
Aditya Gupta
10

Krótko mówiąc, rozmiar Metaspace automatycznie zwiększa pamięć natywną zgodnie z wymaganiami w celu załadowania metadanych klasy, jeśli nie jest to ograniczone -XX:MaxMetaspaceSize

Chandrasekaran
źródło