2016-04-25 20 views
0

Zeichenketten sind unveränderlich und werden im String-Pool verwaltet. Ich möchte wissen, wie dieser Pool verwaltet wird. Wenn eine große Anzahl von String-Literalen in einer Anwendung verwendet wird (ich verstehe, String Builder sollte verwendet werden, wenn Änderungen wie append, replace-Operationen mehr sind), dann steigert Pool die Leistung der Anwendung, indem die neuen String-Objekte nicht immer wieder neu erstellt werden aber mit den gleichen Objekten, die im Pool vorhanden sind, ist dies möglich, da Strings unveränderlich sind und dies keine negativen Auswirkungen hat.Funktioniert String Pool in Java wie LRU-Cache?

Meine Frage ist, wie dies String Pool verwaltet wird. Wenn es eine große Häufigkeit von einigen 'k' Strings gibt und es möglicherweise nur wenige andere String-Objekte gibt, die einmal erstellt wurden und nicht erneut verwendet werden. Möglicherweise werden andere neuere String-Literale verwendet.

In solchen Fällen verhält sich String Pool wie der LRU Cache, wobei die Verweise auf die zuletzt verwendeten Literale gehalten werden und die älteren nicht verwendeten Zeichenfolgen aus dem Pool entfernt werden?

Hat String Pool eine Größe oder können wir es in unserer Anwendung kontrollieren?

Edit:

Normalerweise geben wir Größe der benutzerdefinierten Objektpools wir implementieren. Ich frage mich, warum Feature wie LRU nicht für Sting Pools da ist. Dies könnte ein Merkmal gewesen sein. Bei großen Strings hätte es auch kein Problem gegeben. Aber ich fühle es so, wie es umgesetzt wurde, aber ich wollte nur wissen, warum es nicht da ist, ich meine, es ist aus irgendeinem berechtigten Grund nicht da, hätte dieses Merkmal einige negative Auswirkungen gehabt. Wenn jemand diese negativen Auswirkungen beleuchten könnte, wäre das gut.

Antwort

3

String-Pool ist kein LRU-Cache, da die Einträge nicht herausgenommen werden, außer GC'd.

Es gibt 2 Möglichkeiten, Einträge im String-Pool zu erhalten. String-Literale gehen automatisch dorthin und neue Einträge können mit String.intern() hinzugefügt werden, es sei denn, die String existiert bereits im Pool. In diesem Fall wird ein Verweis darauf zurückgegeben.

Die Werte sind Müll gesammelt, wenn es keine weiteren Verweise auf sie sind, die für die String-Literale (z.B. String-Konstanten) etwas härter als diejenigen sein können, die intern() ed waren.

Die Implementierung hat sich zwischen Java 6 und Java 8 (und sogar zwischen kleineren Versionen) stark verändert. Die Standardgröße des String-Pools ist scheinbar 1009, kann aber mit dem Parameter -XX:StringTableSize=N (seit Java 7) geändert werden. Diese Größe ist die Tabellengröße einer internen Hash-Tabelle, so dass sie höher abgestimmt werden kann, wenn Sie eine Menge von intern() verwenden (für String-Literale sollte es reichlich sein). Die Größe betrifft nur die Geschwindigkeit intern() Aufruf, nicht die Menge der Strings, die Sie internieren können.

Grundsätzlich, es sei denn, Sie verwenden intern() schwer (vermutlich aus einem guten Grund), gibt es sehr wenig Grund, sich um den String-Pool zu kümmern. Zumal es nicht mehr in PermGen gespeichert ist, so dass es nicht mehr sehr leicht OutOfMemoryErrors verursachen kann.

Source.