Warum gibt es MaxPermSize?
Antworten
Zu viele Anzeigen?Hier ist ein guter Artikel über die permanente Erzeugung im Garbage Collector:
Vorstellung der permanenten Generation auf Weblog von Jon Masamitsu
EDIT :
Ich habe nichts gesehen, was darauf hindeutet, warum sie die Entscheidung getroffen haben, die Größe der permanenten Generation zu begrenzen. Ich kann mir aber vorstellen, dass es dafür mehrere Gründe gab.
-
Es macht es viel einfacher zu implementieren, GCs sind entschieden nicht trivial, so dass die Vereinfachung Ihrer Implementierung in irgendeiner Weise ist wahrscheinlich eine gute Idee.
-
YAGNI (You aint gonna need it) die meisten Anwendungen laden eine feste Anzahl von Klassen und in der Regel ist es nicht besonders groß, so dass sie wahrscheinlich für den gemeinsamen Fall optimiert haben und wählte nur eine vernünftige Standard und ließ es konfigurierbar.
-
Angenommen, Ihre Perm-Gen-Größe wird unvorhersehbar groß, dann haben Sie wahrscheinlich einen Fehler in einem Klassenlader (oder Sie müssen Ihre Architektur überdenken). Selbst in Anwendungen, die Klassen zur Laufzeit generieren (oder andere derartige Tricks anwenden), ist die Anzahl der generierten Klassen in der Regel ebenfalls festgelegt, so dass Sie in der Lage sein sollten, maxperm auf Ihre Bedürfnisse abzustimmen.
-
Ich bin kein Experte für alle Details des Java-Klassenladens und der Garbage Collection, aber sie sind beide komplizierte Teile der JVM, also stelle ich mir vor, dass sie versuchen würden, diese beiden Komponenten so orthogonal wie möglich zu halten, und wenn man zulässt, dass das Perm-Gen dynamisch wächst, würden diese beiden Komponenten wahrscheinlich auf komplizierte Weise miteinander gekoppelt (vor allem, weil beide Komponenten ernsthafte Threading-Überlegungen haben)
-
Es gibt wahrscheinlich einige Leistungsvorteile, die maximale Perm-Generation zu begrenzen. Wenn man sie wachsen lässt, könnte dies zusätzliches Kopieren der Sammlung bedeuten, oder es könnte bedeuten, dass Ihre Perm-Generation nicht mehr in einem zusammenhängenden Adressraum existiert, was sich auf die Art und Weise auswirken könnte, wie Ihre anderen Algorithmen zur Verwaltung der Sammlung funktionieren.
Natürlich sind dies alles Spekulationen. Aber selbst wenn das alles falsch ist, glaube ich nicht, dass es "idiotisch" ist, dass Sun eine feste Größe gewählt hat. Es gibt wahrscheinlich viel mehr technische und Implementierungsüberlegungen, als ich mir vorstellen kann :)
Um eine etwas andere Sichtweise zu präsentieren: Die IBM JVM hat keinen Permgen, sondern wendet sich an das Betriebssystem und weist Speicherstücke zu, wenn sie diese benötigt. (Gerüchten zufolge tut jrockit dasselbe, aber ich kann das nicht mit Sicherheit bestätigen).
Dies hat den Vorteil, dass man nicht an eine (scheinbar) willkürliche Grenze stößt und das System auf legitime Wachstumssituationen abstimmen muss.
Auf der anderen Seite ist es ein Problem für Runaway-Applikationen (die im Wesentlichen Leck-Klassen) - die JVM wird im Wesentlichen gehen und verbrauchen alle Speicher in den Adressraum. Dies kann dazu führen, dass nativer Code plötzlich bei malloc()-Aufrufen versagt, oder dass Java auf seltsame Weise zusammenbricht - z. B. weil es nicht in der Lage ist, neue Threads zuzuweisen (was Speicher für den Stack verbraucht). Ein weiterer Nachteil ist, dass es keine "Kostensicherheit" darüber gibt, wie viel Speicher ein Teil der JVM verbrauchen wird.
Es ist also ein Kompromiss - wie wollen Sie in Szenarien mit "potenzieller Schlechtigkeit" scheitern?
Er existiert, weil er hilft, das Garbage Collection Subsystem innerhalb der JVM zu optimieren. Je nach zugrundeliegender Architektur und Speicherverwaltung kann eine JVM-Implementierung eine suboptimale Garbage Collection haben (z.B. zu schnell) ... Sie können eine MaxPermSize von Hand angeben, anstatt sie berechnen zu lassen, damit sich die Anwendung reibungslos verhält...
Die permanente Generation wird verwendet, um die VM selbst zu reflektieren, z. B. Klassenobjekte und Methodenobjekte. Diese reflektierenden Objekte werden direkt der permanenten Generation zugewiesen, die unabhängig von den anderen Generationen dimensioniert ist. Im Allgemeinen kann die Größe dieser Generation ignoriert werden, da die Standardgröße ausreichend ist. Programme, die viele Klassen laden, benötigen jedoch möglicherweise eine größere permanente Generation.
PermSize ist zusätzlicher separater Heap-Speicherplatz zu dem vom Benutzer eingestellten Wert -Xmx. Der für die permanente Erzeugung reservierte Teil des Heaps enthält alle reflektierenden Daten für die JVM. Sie sollten die Größe entsprechend anpassen, wenn Ihre Anwendung viele Klassen dynamisch lädt und entlädt, um die Leistung zu optimieren. Grundsätzlich speichert der Heap die Objekte und die permanente Generierung die Informationen über die Objekte darin. Je größer der Heap also ist, desto größer muss auch das Perm Gen sein.
Standardmäßig beträgt MaxPermSize 32 MB für -client und 64 MB für -server. Wenn Sie jedoch weder PermSize noch MaxPermSize festlegen, wird der gesamte Heap nicht vergrößert, es sei denn, es wird benötigt. Wenn Sie sowohl PermSize als auch MaxPermSize festlegen, z.B. 192 MB, wird der zusätzliche Heap-Speicherplatz beim Starten zugewiesen und bleibt auch zugewiesen.
- See previous answers
- Weitere Antworten anzeigen