Am 19. August veröffentlichte Oracle JDK 8u20. JDK 8u20 enthält viele neue Funktionen, wie z. B. Java-Compiler-Updates, Unterstützung für die Änderung von MinHeapFreeRatio- und MaxHeapFreeRatio-Parametern über APIs zur Laufzeit sowie neue GC-Tuning-Guide-Dokumente. Unter den vielen neuen Funktionen ist jedoch die String-Deduplizierung die am meisten erwartete. Die Reduzierung der Speichernutzung war schon immer ein ewiges Thema. In Java-Anwendungen wird häufig festgestellt, dass das String-Objekt 30 % des Anwendungsspeichers einnimmt. Es ist eines der am häufigsten verwendeten Objekte in Java. Die neue String-Deduplizierungsfunktion kann dazu beitragen, den Speicherbedarf von String-Objekten in Anwendungen zu reduzieren. Derzeit ist diese Funktion nur für den G1-Garbage Collector verfügbar und standardmäßig nicht aktiviert.
Fabian Lange erklärt, wie String-Deduplizierung umgesetzt wird:
Kopieren Sie den Codecode wie folgt:
Der Garbage Collector markiert das Zeichenarray des String-Objekts, wenn darauf zugegriffen wird, und speichert den Hashwert des Strings und die schwache Referenz in einem Array. Wenn der Garbage Collector ein anderes String-Objekt mit demselben Hashwert findet, vergleicht er die beiden Objekte Zeichen für Zeichen. Wenn sie genau übereinstimmen, wird ein String so geändert, dass er auf das Zeichenarray des anderen Strings verweist. Da auf das erste Zeichenarray nicht mehr verwiesen wird, kann es recycelt werden. Der Garbage Collector wird versuchen, die Kosten des gesamten Vorgangs zu reduzieren. Wenn beispielsweise ein String-Objekt gescannt wird und keine Duplikate gefunden werden, wird es in der nächsten Zeit nicht erneut überprüft.
Als nächstes erklärte Fabian Lange den magischen Effekt der String-Deduplizierung durch Code. Führen Sie zunächst den folgenden Code mit Java 8 Update 20 mit den Parametern -Xmx256m -XX:+UseG1GC aus:
Kopieren Sie den Codecode wie folgt:
öffentliche Klasse LotsOfStrings {
private static final LinkedList<String> LOTS_OF_STRINGS = new LinkedList<>();
public static void main(String[] args) löst eine Ausnahme aus {
int Iteration = 0;
while (wahr) {
for (int i = 0; i < 100; i++) {
for (int j = 0; j < 1000; j++) {
LOTS_OF_STRINGS.add(new String("String " + j));
}
}
Iteration++;
System.out.println("Survived Iteration: " + iteration);
Thread.sleep(100);
}
}
}
Die Ausführung des Codes wird aufgrund der OutOfMemoryError-Ausnahme nach 30 Schleifen beendet. Nach Verwendung der Parameter -XX:+UseStringDeduplication -XX:+PrintStringDeduplicationStatistics zur Aktivierung der String-Deduplizierungsfunktion kann das Programm über einen längeren Zeitraum ausgeführt werden. Sie können außerdem über die JVM-Protokolle mehr über die Details des gesamten Deduplizierungsprozesses erfahren. Leser werden gebeten, es selbst zu testen.
Abschließend erläuterte Fabian Lange auch den Unterschied zwischen String-Deduplizierung und String-Residency. Sie sind sich sehr ähnlich, mit der Ausnahme, dass die String-Residency die gesamte String-Instanz wiederverwendet, während die String-Deduplizierung nur auf das Zeichenarray von String abzielt.
(Volltext endet)