2014-11-25 24 views
69

Do wersji 7 Java znajdował się obszar pamięci JVM o nazwie PermGen, w którym JVM korzystał z klas. W wersji Java 8 został on usunięty i zastąpiony obszarem o nazwie Metaspace.Jaka jest różnica między PermGenem a Metaspace?

Jakie są najważniejsze różnice między PermGenem a Metaspace?

Jedyna różnica jaką znam, to to, że java.lang.OutOfMemoryError: PermGen space nie może być już rzucany, a parametr VM MaxPermSize jest ignorowany.

+0

pierwszy wynik google: http://www.infoq.com/articles/Java-PERMGEN-Removed – the8472

+0

@ the8472 Tak, ale to (i wiele innych) wyników google opisuje tylko mechanizm Metaspace, nie wspominając nic o dokładnych różnicach między tym a PermGenem. – Kao

Odpowiedz

77

Główna różnica z punktu widzenia użytkownika - co moim zdaniem poprzednia odpowiedź nie przecenić - jest to, że Metaspace domyślnie wzrasta auto jego rozmiar (aż do podstawowego systemu operacyjnego), podczas gdy PermGen ma zawsze ustalony maksymalny rozmiar. Możesz ustawić stałe maksimum dla Metaspace z parametrami JVM, ale nie możesz automatycznie zwiększyć PermGen.

W dużym stopniu jest to tylko zmiana nazwy. Wracając, gdy wprowadzono PermGen, nie było ładowania Java EE lub dynamicznego (un), więc po załadowaniu klasy było zablokowane w pamięci, aż JVM się wyłączy - czyli Permanentna Generacja. Obecnie klasy mogą być ładowane i rozładowywane w czasie trwania JVM, więc Metaspace ma więcej sensu w obszarze, w którym przechowywane są metadane.

Oba zawierają instancje java.lang.Class i oba z nich cierpią na ClassLoader leaks. Jedyną różnicą jest to, że z domyślnymi ustawieniami Metaspace, trwa to dłużej, dopóki nie zauważysz symptomów (ponieważ auto zwiększa się tak bardzo, jak to tylko możliwe), tzn. Po prostu odsuwasz problem dalej, nie rozwiązując go. OTOH Wyobrażam sobie, że efekt wyczerpania pamięci systemu operacyjnego może być poważniejszy niż tylko wyczerpanie Permgenu JVM, więc nie jestem pewien, czy jest to znaczna poprawa.

Niezależnie od tego, czy używasz JVM z PermGenem czy z Metaspace, jeśli robisz dynamiczne rozładowywanie klas, powinieneś podjąć kroki przeciw wyciekom klasyloadera, na przykład używając mojego ClassLoader Leak Prevention library.

+3

Ani Permgen, ani Metaspace nie zawierają instancji klasy Class. Zachowują tylko meta informacje o załadowanych klasach. Instancje klasy klasy przechowywane są w regularnych stertach, na przykład w innych klasach. –

+0

Ładne porównanie. Dzięki – Sandeep

23

Bye, Bye PermGen, Hello Metaspace

PermGen został całkowicie usunięty.

Metaspace zbieranie śmieci - zbieranie śmieci z martwych klas i classloaders jest wyzwalany po Metadane klasa osiągnie MaxMetaspaceSize.

Przestrzeń Metadata odbyło się już nie przylega do Java heap The metadata teraz przeniósł się do rodzimej pamięci na obszarze znanym jako Metaspace.

w prostych słowach,

Ponieważ klasa jest przydzielona metadanych z rodzimej pamięci, maksymalna dostępna przestrzeń jest całkowita dostępna pamięć systemu. W ten sposób nie będzie już można spotkać się z OOM errors i może skończyć się wyciek do przestrzeni wymiany.

Usunięcie PermGen nie oznacza, że ​​problemy z wyładowaniem modułu ładującego klasy zniknęły. Tak, tak, nadal będziesz musiał monitorować zużycie i odpowiednio planować, ponieważ przeciek doprowadziłby do zużycia całej twojej pamięci macierzystej.

niektórych innych artykułów z analizy: Link1, Link2 i this

+6

Zamiast MaxPermGen masz MaxMetaspaceSize, więc nie ma powodu, aby używał więcej lub mniej pamięci lub masz mniej kontroli. –

5

W krótkich, Metaspace wielkości auto wzrostu rodzimej pamięci jako metadane wymagane do załadowania klasy, jeśli nie wyłącznie z -XX:MaxMetaspaceSize