© Swill Klitch/Shutterstock.com
Exkursionen in die Deduplikation

Von Traumcodes und mehr …


Wann werden Strings dedupliziert? Wie können wir herausfinden, ob sie in unserer Anwendung Vorteile bringen? Wie hoch sind die Kosten bezüglich der CPU? Wir versuchen zu zeigen, wie wir in der Deduplikationsstatistik der JVM die Antworten finden können.

Nach meinem Talk auf der jPrime 2019 [1] fragte mich jemand, wie er erkennen könne, wie effektiv die Stringdeduplikation in seiner Anwendung sein würde. Für diese Messung finde ich den Blick auf die Response Rates und den Speicherverbrauch am effektivsten. Denn was hilft es letztlich, wenn wir Speicher gespart haben, aber unsere Performance schlechter ist? Speicher ist billig. Andererseits führt weniger Speicherverbrauch zu einer geringeren Zahl an erreichbaren Objekten und kann uns daher eine höhere Geschwindigkeit bieten.

Nachdem ich mich fragte, wie ich mir die Deduplikationsdaten ansehen könnte, erinnerte ich mich an das Flag -XX:+PrintStringDeduplicationStatistics in Java 8. In Java 9 mit Unified Logging veränderte es sich zu -Xlog:stringdedup*=debug. Jedes Mal, wenn die Deduplikation ausgelöst wird, wird eine Menge nützlicher Informationen ausgeworfen (Listing 1).

Listing 1

Concurrent String Deduplication (90.162s) Concurrent String Deduplication 72.0B->24.0B(48.0B) avg 59.8% (90.162s, 90.162s) 0.020ms Last Exec: 0.020ms, Idle: 16740.738ms, Blocked: 0/0.000ms Inspected: 3 Skipped: 0( 0.0%) Hashed: 0( 0.0%) Known: 0( 0.0%) New: 3(100.0%) 72.0B Deduplicated: 2( 66.7%) 48.0B( 66.7%) Young: 2(100.0%) 48.0B(100.0%) Old: 0( 0.0%) 0.0B( 0.0%) Total Exec: 3/1.014ms, Idle: 3/89992.409ms, Blocked: 0/0.000ms Inspected: 8457 Skipped: 0( 0.0%) Hashed: 610( 7.2%) Known: 5640( 66.7%) New: 2817( 33.3%) 86.7K Deduplicated: 1810( 64.3%) 51.8K( 59.8%) Young: 1810(100.0%) 51.8K(100.0%) Old: 0( 0.0%) 0.0B( 0.0%) Table Memory Usage: 187.7K Size: 4096, Min: 1024, Max: 16777216 Entries: 6644, Load: 162.2%, Cached: 0, Added: 6645, Removed: 1 Resize Count: 2, Shrink Threshold: 2730(66.7%), Grow Threshold: 8192(200.0%) Rehash Count: 0, Rehash Threshold: 120, Hash Seed: 0x0 Age Threshold: 3 Queue Dropped: 0 

Jedes Mal, wenn ein Young GC (auch Scavenge oder Partial GC genannt) ausgelöst wird, erhöht sich das Alter unserer Survivors. Wenn sie die Tenuring-Schwelle erreichen, werden sie von den jüngeren zu den älteren Regionen verschoben. Standardmäßig werden Strings dedupliziert, wenn sie das Alter 3 erreichen, also bei ihrem dritten Young GC. Wir wollen das nicht früher tun, denn Deduplikation kostet wertvolle CPU-Zyklen. Wenn der String nicht bis ins hohe Alter überlebt, braucht man auch nicht versuchen, Speicher zu sparen. Falls aus irgendeinem Grund der String vorzeitig zu Old befördert wird, wird er auch früher dedupliziert.

Der DeduplicationExplorer

Um all das auszuprobieren, entwickelte ich meinen DeduplicationExplorer. Er wird euch am meisten nutzen, wenn ihr ihn selbst ausführt. Die Verbindung wird via telnet localhost 8080 hergestellt. Dann können Texte und Befehle an ihn gesendet werden. Der gesamte Text wird in einer ArrayList gespeichert. Das sind ...

Neugierig geworden? Wir haben diese Angebote für dich:

Angebote für Teams

Für Firmen haben wir individuelle Teamlizenzen. Wir erstellen Ihnen gerne ein passendes Angebot.

Das Library-Modell:
IP-Zugang

Das Company-Modell:
Domain-Zugang