Speicherbereinigung Pool

nrg

Top Contributor
Hallo Zusammen,

jetzt mal eine Frage, die mir schon lange auf den Lippen liegt. Strings werden ja bekanntlich, falls literal (was ja auch jeder so macht), im Pool abgelegt. Der GC kümmert sich ja nur um den Heap. In einer permanent laufenden Applikation fallen mit Sicherheit massig Literale an. Natürlich wird es jedes Stringobjekt nur ein einziges mal im Pool geben, weil das zur Speicheroptimierung der JVM gehört aber trotzdem gibt es ja abermillionen Kombinationen von Strings.
Was verhindert, dass dieser Pool nicht irgendwann überläuft?
 

Sonecc

Gesperrter Benutzer
Meines Wissens nach ist der String Pool im Heap enthalten.
Jeder String ist ein Objekt und jedes Objekt ist im Heap. Der String Pool ist auch etwas anders zu verstehen, er ist kein eigener Speicherbereich, sondern die zusammenfassung gleicher Strings.

Beispiel:

Java:
String a = "abc";
String b = "abc";

Der Compiler macht daraus nicht zwei String Objekte, sondern ein einzelnes, welches im Heap liegt. Vergleiche dafür mal:

Java:
String a = "abc";
String b = "abc";
System.out.println(a == b);

Ergibt true.
 

nrg

Top Contributor
also letzteres habe ich schon verstanden bzw. war auch nicht meine Frage :)

Natürlich wird es jedes Stringobjekt nur ein einziges mal im Pool geben, weil das zur Speicheroptimierung der JVM gehört aber trotzdem gibt es ja abermillionen Kombinationen von Strings.



die erste Aussage war aber für mich ganz interessant. Also wird deiner Meinung nach, der Pool ebenfalls vom GC bereinigt? Da habe ich in diesem Forum mal anderes gehört (glaube das war hdi). Wenn das natürlich nicht stimmte und der GC ebenfalls dafür zuständig ist, hat sich die Frage eigentlich schon erledigt ;)
 
G

Gastredner

Gast
Wenn ich mich nicht irre, dann werden nur Literale in diesem Pool abgelegt. Da man in Anwendungen aber eher selten alles hartkodiert in den Quelltext schreibt und stattdessen eher die benötigten Strings aus properties-Dateien o. Ä. ausliest, sollte dies eigentlich kein Problem darstellen.
 

Sonecc

Gesperrter Benutzer
(...) it's a collection of references to String objects. Strings, even though they are immutable, are still objects like any other in Java. Objects are created on the heap and Strings are no exception. So, Strings that are part of the "String Literal Pool" still live on the heap, but they have references to them from the String Literal Pool.
http://www.javaranch.com/journal/200409/ScjpTipLine-StringsLiterally.html

Der String an sich, liegt damit im Heap und wird vom GC verwaltet.
Ich sehe aber grade, als ich das ganze mal bis zum Ende gelesen habe, dass das Literal durch die Referenz im Pool immer refenziert ist und damit scheinbar nie vom GC weggeräumt werden kann...
 
M

maki

Gast
Was verhindert, dass dieser Pool nicht irgendwann überläuft?
Der Pool landet früher oder später im PermGen Space, der wird nie vom GC aufgeräumt, man bräuchte aber schon eine Menge an litaralen um eine OutOfMemoryException zu provozieren.
Der PermGen Space wird aber auch für andere, lang- bzw "ewig-" lebende Objekte genutzt, Klassen zB.
In (Server-)Anwendungen die lange laufen, kann das schon zum Problem werden.
 

nrg

Top Contributor
Ich sehe aber grade, als ich das ganze mal bis zum Ende gelesen habe, dass das Literal durch die Referenz im Pool immer refenziert ist und damit scheinbar nie vom GC weggeräumt werden kann...

wobei wenn auf diese Referenz im Pool keine Referenz von der Applikation existiert, könnte man das ja als "Softreference" bezeichnen, die dann bei Bedarf beseitigt werden kann. Aber nachdem der GC sich imho nicht um den Pool kümmert, frage ich mich, wer oder was das sonst machen sollte?

@Gastredner: was ist denn mit Methoden, die einen String liefern? Also z.b. ein replace auf einen String liefert ja einen neuen String. Landet dieser dann wieder im Pool? Wenn nein, wäre der string literal pool ja mit der Aussage geklärt aber was ist mit dem string constant pool? Zwar werden Stringverkettungen in Schleifen, wenn gut programmiert, mit einem StringBuilder gemacht und wenn nicht afaik vom compiler optimiert aber man macht ja nicht jede Verkettung im Code mit einem StringBuilder. Durch einige Verkettungen in einer dauerhaft laufenden Applikation können sich, so wie ich das sehe, auch sehr viele Objekte im String constant pool ansammeln. Was ist mit denen? :)
 

Sonecc

Gesperrter Benutzer
wobei wenn auf diese Referenz im Pool keine Referenz von der Applikation existiert, könnte man das ja als "Softreference" bezeichnen, die dann bei Bedarf beseitigt werden kann. Aber nachdem der GC sich imho nicht um den Pool kümmert, frage ich mich, wer oder was das sonst machen sollte?
Laut meinen Recherchen gibt es Implementierung der JVM, welche genau das machen, also String Literale aufräumen, welche nur vom Pool aus referenziert werden. Halte das aber inzwischen auch für relativ unnötig.

Also z.b. ein replace auf einen String liefert ja einen neuen String. Landet dieser dann wieder im Pool?
Nein, entweder ist es der alte String oder ein neuer String, welcher mittels new erzeugt wurde. Das wiederum ist kein String literal und landet daher nicht im Pool. Im Pool landen eben nur Literale und keine Objekte (new String("bla") ist nunmal ein Objekt und wird als solches behandelt)
 

nrg

Top Contributor
Nein, entweder ist es der alte String oder ein neuer String, welcher mittels new erzeugt wurde. Das wiederum ist kein String literal und landet daher nicht im Pool. Im Pool landen eben nur Literale und keine Objekte (new String("bla") ist nunmal ein Objekt und wird als solches behandelt)

Kleinlich könnte man jetzt sagen, dass Literale ja auch Objekte sind aber ich weiß schon wie du es meintest ;). Wenn der return eines replace o.ä. mit new erzeugt wird, wäre der String literal pool ja geklärt. Dadurch kommen dann wirklich nicht soviele Objekte zusammen... Beim String constant pool (worin afaik sowas landet wie
Code:
"Ha" + "llo" + "Welt"
) sehe ich das allerdings noch etwas kritischer (s. oben).
Wobei maki ja schon die entscheidende Info gegeben hat. Warum solche Softreferences von der JVM nicht beseitigt werden, wenn das teilweiße sogar problematisch werden kann, ist mir allerdings etwas unklar...
 

Sonecc

Gesperrter Benutzer
Und ja, Literale sind Objekte, aber die werden nunmal besonders behandelt. Bei den mit new erzeugten ist das nicht so. Dachte eigentlich das mein Text kein Interpretationsspielraum zulässt :/

...

Ich verwirre mich grad selbst -.-
 
Zuletzt bearbeitet:
M

maki

Gast
Warum solche Softreferences von der JVM nicht beseitigt werden, wenn das teilweiße sogar problematisch werden kann, ist mir allerdings etwas unklar...
Mit "Softreferences hat das nix zu tun ;)

Wie Sonecc schon andeutete, hat nur die Sun VM einen PermGenSpace, und selbst für die gab es andere Pläne für Java 7. k.A. ob das umgesetzt wurde.
Andere VMs haben da andere Vorgehenweisen.

Hier ein ausführlicher Artikel über den GC der Sun JVM 5: Tuning Garbage Collection with the 5.0 Java[tm] Virtual Machine

Kurz: Was im PermGenSpace landet, wird nie mehr Collected vom GC, da landen nur Objekte, die schon sehr viele GC Läufe überstanden haben.
Ist natürlich doof wenn der Server nach 6 Monaten ein Update der App bekomt, und danach trotzdem alle alten Klassen noch im PermGenSpace rumliegen.
 

nrg

Top Contributor
Mit "Softreferences hat das nix zu tun ;)

ja der Begriff war etwas falsch gewählt, deshalb auch die Anführungszeichen ;).
Aber für mich ist ein Objekt, auf das in der Applikation keine Referenz mehr existiert und eigentlich nurnoch im Heap gehalten wird, weil es der Pool referenziert, nutzlos. Diese Objekte könnte man doch bei Bedarf wegräumen :oops:

edit: aber gut, ist eigentlich alles gesagt. danke allen für die info :)
 

Sonecc

Gesperrter Benutzer
Ist ja nicht so, als könntest du die Objekte nicht mehr nutzen. Mittels der intern() Methode kannst du noch immer darauf zugreifen.
 

Ähnliche Java Themen

Neue Themen


Oben