Osobiście nie uważałbym PermGen za specjalną część kupy.
Wolałbym myśleć o sterty jako o obszarze pamięci przeznaczonym do przechowywania instancji obiektów, podczas gdy PermGen jako o obszarze przeznaczonym do przechowywania definicji klas. W rezultacie cykl życia sterty jest powiązany z aplikacją, podczas gdy cykl życia PermGen jest powiązany z maszyną JVM.
Jednym z najlepszych przykładów tego, dlaczego aplikacja i jej JVM mogą mieć inny cykl życia, jest kontener Java EE. Na serwerze aplikacji można wdrażać i cofać wdrażanie aplikacji bez ponownego uruchamiania serwera. Podczas cofania wdrożenia (lub ponownego wdrożenia) łatwo jest zwolnić wszystkie instancje obiektów, tj. Przestrzeń sterty, ale raczej trudne jest wyczyszczenie wszystkich klas załadowanych przez tę aplikację z PermGen, ponieważ niektóre z klas mogą nadal być przywoływane przez JVM.
Jednym z takich przypadków są nieszczelne sterowniki . Podczas wdrażania aplikacji sterownik JDBC jest ładowany i rejestrowany w DriverManager. Gdy ta aplikacja nie jest wdrożona, DriverManager działa i przechowuje odniesienie do sterownika, jego oryginalnego programu ładującego klasy i wszystkiego, co ładuje ten program ładujący klasy. W rezultacie powstaje wyciek pamięci w PermGen, ale nie jest to wina zarządzania pamięcią aplikacji.
To prawda, że maszyny JVM, takie jak JRocket, w ogóle nie mają PermGen, wszystko jest przechowywane w stosie. Tylko w takim kontekście możesz nazwać PermGen „specjalną częścią” sterty. Nawet wtedy powinniśmy nadal patrzeć na PermGen i stertę inaczej, ponieważ mają one bardzo różne przeznaczenie i mają bardzo różne typy wycieków pamięci.
Aktualizacja : W Oracle JDK 8 PermGen został zastąpiony przez "Metaspace" i jest teraz oficjalnie częścią kupy. Nie będziemy już musieli specjalnie dostrajać PermGen.