Perm Space vs Heap Space

79

Was ist der Unterschied zwischen dem Perm-Speicher und dem Heap-Speicher (Was und wie wählt die JVM die Verwendung der einzelnen Speicherbereiche aus)?

Zweitens, aber vor allem, welches Verhältnis wird für eine Standard-Java-Anwendung vom Typ MVC empfohlen?

Gareth
quelle

Antworten:

79

Der Heap speichert alle von Ihrem Java-Programm erstellten Objekte. Der Inhalt des Heaps wird vom Garbage Collector überwacht, der Speicher vom Heap freigibt, wenn Sie ein Objekt nicht mehr verwenden (dh wenn keine Verweise mehr auf das Objekt vorhanden sind.

Dies steht im Gegensatz zum Stapel , in dem primitive Typen wie Ints und Chars gespeichert sind und in der Regel lokale Variablen und Funktionsrückgabewerte sind. Dies ist kein Müll gesammelt.

Der Dauerwellenraum bezieht sich auf einen bestimmten Teil des Heaps. In dieser SO-Antwort finden Sie eine Erklärung: Was ist Dauerwellenraum?

Olhovsky
quelle
1
Der Link, den Sie gegeben haben, sagt "Segment des Haufens" - ist es also wirklich "ein besonderer Teil des Stapels"? Es wäre viel sinnvoller, wenn es Teil des Heaps (oder sogar eines statischen Datensegments) wäre als der Stapel, der für solche Dinge einfach nicht geeignet ist.
Sergei Tachenov
1
Es ist ein besonderer Teil des Haufens. Ich habe meine Antwort bearbeitet, bevor Sie kommentiert haben, aber ich schätze die Korrektur trotzdem :)
Olhovsky
1
eine Empfehlung zur zweiten Frage?
Gareth
2
@ Gareth: Das ist kein Grund zur Sorge. Einige JVMs haben nicht einmal einen dedizierten Speicherbereich für den Dauerwellenraum. Wenn Sie eine Ausnahme von java.lang.OutOfMemory erhalten, visualisieren Sie, wie viel Dauerwellenraum mit diesem Tool verwendet wird: alphaworks.ibm.com/tech/pmat , und wenn Sie keinen Dauerwellenraum mehr haben (meiner Erfahrung nach selten), können Sie dies tun Erhöhen Sie die Dauer des Perm-Speicherplatzes mit der Befehlszeilenoption -XX:MaxPermSize=256m, um die Größe des Perm-Speicherplatzes auf 256 MB festzulegen.
Olhovsky
1
OK, ich verstehe. Es gibt also wirklich keine Prozentregel oder so. Vielen Dank.
Gareth
34

Persönlich würde ich PermGen nicht als besonderen Teil des Haufens betrachten.

Ich würde Heap lieber als Speicherbereich zum Speichern von Objektinstanzen betrachten, während PermGen als Bereich zum Speichern von Klassendefinitionen dient. Infolgedessen ist der Lebenszyklus eines Heaps an eine Anwendung gebunden, während der Lebenszyklus von PermGen an eine JVM gebunden ist.

Eines der besten Beispiele dafür, warum eine Anwendung und ihre JVM einen unterschiedlichen Lebenszyklus haben können, befindet sich in einem Java EE-Container. In einem App-Server können Anwendungen bereitgestellt und nicht bereitgestellt werden, ohne den Server neu zu starten. Während der Aufhebung der Bereitstellung (oder erneuten Bereitstellung) ist es einfach, alle Objektinstanzen, dh den Heap-Speicherplatz, freizugeben. Es ist jedoch ziemlich schwierig, alle von dieser App geladenen Klassen aus PermGen zu löschen, da einige der Klassen weiterhin von der JVM referenziert werden können.

Einer dieser Fälle sind die undichten Treiber . Wenn eine App bereitgestellt wird, wird ein JDBC-Treiber geladen und im DriverManager registriert. Wenn diese App nicht bereitgestellt wird, lebt der DriverManager weiter und enthält einen Verweis auf den Treiber, seinen ursprünglichen Klassenlader und alles, was dieser Klassenlader geladen hat. Infolgedessen wird ein Speicherverlust in PermGen erstellt, der jedoch nicht an der Speicherverwaltung der Anwendung liegt.

Es ist wahr, dass JVMs wie JRocket überhaupt kein PermGen haben, alles ist auf einem Haufen gespeichert. Nur in einem solchen Kontext können Sie PermGen als "besonderen Teil" des Heaps bezeichnen. Selbst dann sollten wir PermGen und Heap immer noch unterschiedlich betrachten, da sie einen sehr unterschiedlichen Zweck haben und sehr unterschiedliche Arten von Speicherlecks aufweisen.

Update : In Oracle JDK 8 wird PermGen durch "Metaspace" ersetzt und ist nun offiziell Teil des Heaps. Wir müssen PermGen nicht mehr speziell einstellen.

Christopher Yang
quelle
0

Sie können dem zugewiesenen Speicher im Heap KEINE Namen geben.

Das heißt, int x(sein Name) wird im Stapel zugewiesen. Sie können den Zeiger über seinen Namen erreichen, sodass sich der Zeiger im Stapel befindet. Sie können das Objekt nicht über seinen Namen erreichen, da es keinen Namen hat. Der Zugriff auf das (namenlose) Objekt muss über seinen Zeiger erfolgen.

Pete Del Fina
quelle