1. Hitchhiker‘s Guide
To Java Performance
Ingo Düppe | CROWDCODE
Ingo Düppe | Hitchhiker's Guide To Java Performance 1
2. Ingo Düppe
§ Seit 20 Jahre als Softwareentwickler & Berater
§ Seit 14 Jahre als Trainer & Coach tätig
§ Seit 5 Jahren CEO & Co-Founder von
CROWDCODE GmbH & Co. KG
Ingo Düppe | Hitchhiker's Guide To Java Performance 2
7. Wie sieht denn die
Anwendungstopologien aus?
Was kann denn eigentlich alles in der Anwendung schief gehen?
Ingo Düppe | Hitchhiker's Guide To Java Performance 7
9. Wie äußert
sich denn das Problem?
Ingo Düppe | Hitchhiker's Guide To Java Performance 9
10. Ingo Düppe | Hitchhiker's Guide To Java Performance 10
Wie äußert
sich das
Problem?
Server ist
nicht stabil?
Antwortzeiten
zu langesam?
11. Ingo Düppe | Hitchhiker's Guide To Java Performance 11
Wie äußert
sich das
Problem?
Server ist
nicht stabil?
Antwortzeiten
zu langesam?
Bleibt er
einfach stehen?
Absturz mit
OutOfMemory?
Liegt ein
Deadlock vor?
Dauerhaft?
Zeitweise?
GC
Overhead?
Blockierende
Ressourcen?
ThreadDump
analysieren
Unter Last?
Ohne Last alle paar
Tage / Wochen /
Monate
Speicher
zu klein?
Gibt es einen
Memory Leak?
GC Log
analysieren
HeapDump
analyse
Speicherbedarf
verringern
Speicher effektiv
erhöhen!
GC
konfigurieren
Sperren entfernen
bzw. verkleinern
Weniger
Objekte
erzeugen
Objekte
kleiner
machen
12. Ingo Düppe | Hitchhiker's Guide To Java Performance 12
Server ist
nicht stabil?
Antwortzeiten
zu langesam?
Bei isolierten
einzelnen
Anfragen?
reproduzierbar
unter Last?
sporadisch unter
Last?
Was macht das
System gerade?
Sind es kurze
Abfragen im
Sekundenbereich?
Sind es langlaufende
Abfragen im
Minutenbereich?
Telemetrie
analysieren
Last
erzeugen
Speicher
Profiling
CPU
Profiling
SQL/JPQL
analysieren
Gibt es
blockierende
Threads?
Wird sehr viel
Speicher
verbraucht?
Dauern DB
abfragen
zulange?
Gibt es
Exceptions?
Ist der
Algorithmus
zu langsam?
Audits
analysieren
CopyOnWrite
ReadWrite
Locks
Thread / Monitor
analysieren
Kleinere Sperren o.
mehr Ressourcen
SQL Perf.
Tuning
besseren
Algorithmus
schreiben
Exceptions
vermeiden
13. Ingo Düppe | Hitchhiker's Guide To Java Performance 13
Wie äußert
sich das
Problem?
Server ist
nicht stabil?
Antwortzeiten
zu langesam?
Bleibt er
einfach stehen?
Absturz mit
OutOfMemory?
Liegt ein
Deadlock vor?
Dauerhaft?
Zeitweise?
GC
Overhead?
Blockierende
Ressourcen?
ThreadDump
analysieren
Unter Last?
Ohne Last alle paar
Tage / Wochen /
Monate
Speicher
zu klein?
Gibt es einen
Memory Leak?
GC Log
analysieren
Speicher
analyse
Speicherbedarf
verringern
Speicher effektiv
erhöhen!
GC
konfigurieren
Sperren entfernen
bzw. verkleinern
Bei isolierten
einzelnen
Anfragen?
reproduzierbar
unter Last?
sporadisch unter
Last?
Was macht das
System gerade?
Sind es kurze
Abfragen im
Sekundenbereich?
Sind es langlaufende
Abfragen im
Minutenbereich?
Telemetrie
analysieren
Last
erzeugen
Speicher
Profiling
CPU
Profiling
SQL/JPQL
analysieren
Gibt es
blockierende
Threads?
Wird sehr viel
Speicher
verbraucht?
Dauern DB
abfragen
zulange?
Gibt es
Exceptions?
Ist der
Algorithmus
zu langsam?
Audits
analysieren
CopyOnWrite
ReadWrite
Locks
Thread / Monitor
analysieren
Kleinere Sperren o.
mehr Ressourcen
SQL Perf.
Tuning
besseren
Algorithmus
schreiben
Weniger
Objekte
erzeugen
Objekte
kleiner
machen
Exceptions
vermeiden
15. Java Virtual Machine
Memory Modell
§ Speichernutzung des Java-Prozess
§ Java-Prozess unterliegt den Restriktionen der OS-Architektur
§ Adressierbarkeit
§ 32 Bit ~ 4 GB Speicher
§ 64 Bit ~ 16 Exabytes ( 16 Millionen TB)
§ 31 Bit (Mainframe)
Ingo Düppe | Hitchhiker's Guide To Java Performance 15
Quelle: https://www.ibm.com/developerworks/java/library/j-codetoheap/
16. Memory Modell
Logische Ansicht auf das Java Memory Model
=> Jeder Thread in der JVM hat seinen eigenen Thread Stack
Ingo Düppe | Hitchhiker's Guide To Java Performance 16
Quelle: http://tutorials.jenkov.com/java-concurrency/java-memory-model.html
17. Ingo Düppe | Hitchhiker's Guide To Java Performance
Memory Modell
Quelle: http://tutorials.jenkov.com/java-concurrency/java-memory-model.html
18. Ingo Düppe | Hitchhiker's Guide To Java Performance
Memory Modell
Quelle: http://tutorials.jenkov.com/java-concurrency/java-memory-model.html
19. Ingo Düppe | Hitchhiker's Guide To Java Performance
Memory Modell
Aufteilung Java Heap
19
Eden Space
Survivor
Space
Old Gen
Permgen
Space
20. Permgen vs metaspace
§ Metaspace in Java 8
§ Permgen ist komplett entfernt worden
§ PermSize und MaxPermSize werden ignoriert
und eine Warnung wird beim starten der Applikation angezeigt
Ingo Düppe | Hitchhiker's Guide To Java Performance 20
Eden Space
Survivor
Space
Old Gen
Permgen
Space
Metaspace
Bis Java 7
Ab Java 8
21. Permgen vs Metaspace
Ingo Düppe | Hitchhiker's Guide To Java Performance 21
Permgen Metaspace (ab Java8)
Permgen hat meist eine fixe maximale
Grösse
Grundsätzlich verändert Metaspace die
Größe des Speichers in Abhängigkeit von
dem verfügbaren nativen Speichers
Java Heap Speicher Nativer Speicher
Maximale Speichergröße kann mit
„XX:MaxPermSize“ gesetzt werden
Maximale Speichergröße kann mit
„XX:MetaspaceSize“ gesetzt werden
Ineffiziente GC mit GC-Pausen Effiziente GC. Deallokiert
Klasseninformationen gleichzeitig und
nicht in den GC-Pausen
23. Java Garbage Collection
§ Elemente im Root Set verweisen direkt auf Objekt im Heap der JVM
§ Referenzvariablen innerhalb dieser Objekte verweisen auf weitere Objekte im Heap
(Indirekt erreichbar vom Root Set)
Ingo Düppe | Hitchhiker's Guide To Java Performance 23
Root Set
Heap
25. Java Garbage Collection
§ Generational Garbage Collection
Ingo Düppe | Hitchhiker's Guide To Java Performance 25
applications written in several programming languages, including the Java programming language:
• Most allocated objects are not referenced (considered live) for long, that is, they die young.
• Few references from older to younger objects exist.
Young generation collections occur relatively frequently and are efficient and fast because the young generation
space is usually small and likely to contain a lot of objects that are no longer referenced.
Objects that survive some number of young generation collections are eventually promoted, or tenured, to the
old generation. See Figure 1. This generation is typically larger than the young generation and its occupancy
grows more slowly. As a result, old generation collections are infrequent, but take significantly longer to
complete.
Figure 1. Generational garbage collection
The garbage collection algorithm chosen for a young generation typically puts a premium on speed, since young
generation collections are frequent. On the other hand, the old generation is typically managed by an algorithm
that is more space efficient, because the old generation takes up most of the heap and old generation
algorithms have to work well with low garbage densities.
Allocation
Promotion
Young Generation
Old Generation
27. Ingo Düppe | Hitchhiker's Guide To Java Performance
GC-Programmfluss
Seriell vs. Parallel vs. Concurrent
27
Seriell Parallel
Quelle: Oracle Corporation
Concurrent
(CMS)
Programmfluss
Garbagecollector
28. Garbage Collection
Die entscheidenden Fragen
§ Serial vs. Parallel
§ Stop the World vs. Concurrent
§ Full vs. Incredimental
§ Throughput vs. max. ResponseTime
Ingo Düppe | Hitchhiker's Guide To Java Performance 28
29. Garbage Collection
Kontinuierliches Aufräumen
§ G1-Collector (ab JDK 8)
§ Shenandoah: Ultra low-pause GC (ab JDK 12 experimental)
Ingo Düppe | Hitchhiker's Guide To Java Performance 29
-XX:PauseIntervallMillis=200
-XX:MaxGCPauseMillis=500
30. Kleine JVM-Parameter-Hilfen
§ Ausgabe aller Schalter einer JVM:
§ java -XX:+PrintFlagsFinal
-XX:+UnlockDiagnosticVMOptions
-XX:+UnlockExperimentalVMOptions
-version
§ Alle Schalter die von „Default“ abweichen
§ java -XX:+PrintCommandLineFlags
Ingo Düppe | Hitchhiker's Guide To Java Performance 30
31. Parallel-CMS-G1
Hinweis: G1 hat ein Entwicklungsprozess hinter sich und wahrscheinlich vor sich.
Ingo Düppe | Hitchhiker's Guide To Java Performance 31
Parallel CMS G1
Vorhanden Java 6 Update 14
Supported Java 7 update 4
Standard Java 6,7,8 (server) nie Java 9 (JEP 248)
Einsatzzweck Durchsatz bei vielen
Kernen
Durchsatz oder
kleinen Heaps
Bei Großen Heaps und
kleinen Pausenzeiten
33. Garbage Collector Log
§ GC-Log mit folgenden VM-Parametern erstellen:
Ingo Düppe | Hitchhiker's Guide To Java Performance 33
java -Xloggc:gc.log
-XX:+PrintGCDetails
-XX:+PrintGCTimeStamps
-XX:+PrintTenuringDistribution
34. Ingo Düppe | Hitchhiker's Guide To Java Performance 34
35. GC unter Last,
was passiert?
Ingo Düppe | Hitchhiker's Guide To Java Performance 35
36. Wie reduziere
ich den Speicherbedarf?
Weniger oder kleinere Objekte
Ingo Düppe | Hitchhiker's Guide To Java Performance 36
37. Anatomie eines Java Objekts (Integer 32-Bit)
§ Verhältnis von int zu Integer ist 1:4
§ Menge der Metadaten für ein Objekt variiert bei verschiedenen JVM Versionen
§ Class Pointer auf die Klasseninformation, t
§ Flags Zustandsbeschreibung des Objekts (z.B. Array oder Objekt)
§ Locks Synchronisation
§ Beispiel: java.lang.Integer Objekt für 32-bit Java-Prozess
Ingo Düppe | Hitchhiker's Guide To Java Performance 37
Quelle: http://www.ibm.com/developerworks/java/library/j-codetoheap/
38. Anatomie eines Java Objekts (Integer 32-Bit)
§ Class pointer: Type bzw. bei Array Zeiger auf das Array (int[]-Class)
§ Flags: Status des Objects
§ Locks: Synchronisation
§ Size: (Größe des Array)
Ingo Düppe | Hitchhiker's Guide To Java Performance 38
Array
Quelle: https://www.ibm.com/developerworks/java/library/j-codetoheap/
39. Ein String/Array in der 32-Bit Welt
§ Speicherverbrauch eines String der Länge 8:
§ Größe = 224 + 128 + 8*16 = 480 Bit = 60 bytes
Ingo Düppe | Hitchhiker's Guide To Java Performance 39
Quelle: https://www.ibm.com/developerworks/java/library/j-codetoheap/
40. 32-BIT vs 64-Bit JVM
§ Faustfomel: Heapsize von 32 Bit auf 64 Bit Faktor 1,7
Ingo Düppe | Hitchhiker's Guide To Java Performance 40
Quelle: https://www.ibm.com/developerworks/java/library/j-codetoheap/
41. Ingo Düppe | Hitchhiker's Guide To Java Performance
Speichergröße von Feldern- 32 bzw 64 Bit
JVM
41
32 Bit 64 Bit Array 32 Bit Array 64 Bit
boolean,byte 32 32 8 8
char, short 32 32 16 16
int, float 32 32 32 32
long, double 64 64 64 64
Object fields 32 64 (32*) 32 64(32*)
*-XX:+UseCompressedOops
42. Wie konfiguriere
ich effektiv mehr Speicher?
32- oder 64-Bit JVM?
Ingo Düppe | Hitchhiker's Guide To Java Performance 42
43. JVM: 32 Bit VS 64 Bit
Option bei einer 64 BIT JVM
Was kann „XX:+UseCompressedOops“
Referenzen werden in einer 64 BIT JVM wie in einer 32 BIT JVM abgelegt
=> Spart Speicher
=> Performance kann potenziell verbessert werden
=> Beschränkung auf 32 GB
Ingo Düppe | Hitchhiker's Guide To Java Performance 43
Details: https://wiki.openjdk.java.net/display/HotSpot/CompressedOops
48. Just-in-Time-Compiler
§ Just in Time = Übersetzung in Maschinencode zur Laufzeit, wenn ein Code-Teil benötigt wird
§ Klassischer Ansatz: Ahead of Time = komplett vor der Ausführung
§ HotSpot = JIT-Compiler für Java-Bytecode (seit 1999)
§ Die Kompilierung kostet Zeit und darf deshalb nicht zu aufwendig sein.
§ Teilweise nur für Programmteile, die häufig ausgeführt werden, sogenannte Hotspots
(deswegen auch der Name HotSpot)
§ War 1997 rund doppelt so schnell wie andere JVMs.
§ Zwei Verfahren:
§ Methoden-JITs: Übersetzung kompletter Methoden
§ Tracing-JITs: Übersetzung häufig ausgeführter Pfade in Schleifen
Ingo Düppe | Hitchhiker's Guide To Java Performance 48
49. Just-in-Time-Compiler
§ Just in Time = Übersetzung in Maschinencode zur Laufzeit, wenn ein Code-Teil benötigt wird
Klassischer Ansatz: Ahead of Time = komplett vor der Ausführung
§ HotSpot = JIT-Compiler für Java-Bytecode (seit 1999)
§ Die Kompilierung kostet Zeit und darf deshalb nicht zu aufwendig sein.
§ Teilweise nur für Programmteile, die häufig ausgeführt werden, sogenannte Hotspots
(deswegen auch der Name HotSpot)
§ War 1997 rund doppelt so schnell wie andere JVMs.
§ Zwei Verfahren:
§ Methoden-JITs: Übersetzung kompletter Methoden
§ Tracing-JITs: Übersetzung häufig ausgeführter Pfade in Schleifen
Ingo Düppe | Hitchhiker's Guide To Java Performance 49
50. Just-in-Time-Compiler
§ Phasen der Bytecode-Kompilierung:
§ Bytecode parsen
§ Maschinen-Instruktionen auswählen
§ Global Value Numbering (GVN)
§ Kontrollfluss-Graphen erzeugen
§ Register-Allokation (mithilfe von Graphen-Einfärbung)
§ Peephole-Optimierung (auf Assembler-Ebene)
§ Zyklus innerhalb des JIT-Compilers:
§ Interpretation
§ Optimierung von Hotspots
§ Deoptimierung bei geänderten Voraussetzungen
§ erneute Optimierung
Ingo Düppe | Hitchhiker's Guide To Java Performance 50
55. Analyse der Telemetriken
§ Suche nach Hinweisen,
in welche Richtung die weitere Analyse gehen kann:
§ Wie sieht der GC-Nutzung aus?
§ Wie sieht der Speicherbedarf aus?
§ Wie sieht die CPU-Nutzung aus?
§ Wie sehen die Threads aus?
§ Gibt es Auffälligkeiten bei den SQL/Datenbank-Abfragen?
§ Gibt es Auffälligkeiten bei den IO-Operationen?
Ingo Düppe | Hitchhiker's Guide To Java Performance 55
56. Ok, ich weiß was
das Problem ist.
Was kann ich nun tun?
Ingo Düppe | Hitchhiker's Guide To Java Performance 56
58. Ingo Düppe | Hitchhiker's Guide To Java Performance
Suche nach dem Optimum
58
Aufwand
Änderung Koordination
Optimum
Kopplung
eng lose
80% Pareto-Korridor
Verschiebt sich
nach jedem Zyklus
60. Strategie bei der Optimierung
“We should forget about small efficiencies,
say about 97% of the time: premature optimization is the
root of all evil.”
Donald Knuth
Ingo Düppe | Hitchhiker's Guide To Java Performance 60
61. Zusammenfassung
§ Performance Ziele benennen
§ Anwendungstopologie skizzieren
§ Fehlerbild genau skizzieren
§ Profiler sind nicht kompliziert
§ Grenzsituationen beachten
§ HeapDump, ThreadDump und GC Log nutzen
Ingo Düppe | Hitchhiker's Guide To Java Performance 61
62. CROWDCODE GmbH & Co. KG
In den Appelstücker 1
56412 Ruppach-Goldhausen
CROWDCODE GmbH & Co. KG
Am Mittelhafen 16
48155 Münster
Tel +49 2602 8390030
Mail kontakt@crowdcode.io
Web www.crowdcode.io
Ingo Düppe
ingo.dueppe@crowdcode.io
@javacoding
Vielen Dank
Architektur- & Technologieberatung
Analyse & Konzeption
Softwaredesign & -entwicklung
Training & Coaching