1
2
3
4
Ein Garbage Collector sorgt dafür dass nur die Objekte dir noch erreichbar sind im Speicher bleiben.
Nicht erreichbare O...
5
Malloc muss normalerweise eine Liste freier Speicherbereiche verwalten ->Malloc typischerweise
langsamer als ein new in ...
6
Das eigentliche Problem sind die versteckten Kosten des GC.
Praktisch jede GC Implementierung erfordert eine „stop the w...
7
„Normaler“ Garbage Collector log
http://www.tagtraum.com/gcviewer.html
Der Speicherverbrauchstrend zeigt keinen Anstieg....
8
9
Shallow size == flache Grösse des Objektes. Die Shallow Size ist in der Praxis ein nützliches Maß für
den Overhead eines...
10
Man beachte :
Mehrere Stringobjekte können das gleiche char[] verwenden (sharing)
Selbst ein leerer String braucht mehr...
11
Diese Werte beziehen sich auf eine SUN JVM für 32 bit Intel Prozessoren. Bei anderen JVM‘s oder
anderen Prozessoren kan...
12
Unter 64 bit braucht eine Java Applikation signifikant mehr Speicher als unter 32 bit, weil Referenzen
8 Byte statt 4 B...
13
In diesem vereinfachten Beispiel können folgende Schlüsse aus den Daten gezogen werden :
Es wird am meisten Speicher in...
14
Da die shallow size in der Praxis nicht sehr nützlich ist, braucht man ein Maß für die Menge des
Speichers die festgeha...
15
Hier ist ein Beispiel der LinkedList Klasse aus dem JDK dargestellt
16
17
18
Ein Heap Dump ist ein File, dass alle „noch lebendenden“ Java Objekte zu einem bestimmten
Zeitpunkt enthält.
„Noch lebe...
19
Dies gilt zumindest für die SUN/SAP JVM.
Andere JVM‘S (IBM) schreiben Heap Dumps, die einige Informationen nicht enthal...
20
Es gibt einige verschiedene Möglichkeiten einen Heap dump zu erzeugen
21
Die Option
22
23
Das IBM Heap Dump Format wird durch ein zusätzliches Plugin unterstützt
MAT kann sowohl standalone als auch innerhalb v...
24
Wichtige Funktionen
Class histogramm
Show object
Retained size
Retained set
25
26
Objekte mit großer retained Size in einem großen Heap Dump mit Millionen von Objekten zu finden
ist manuell sehr schwie...
27
Das Business Objekt vom Typ com.myerp.buyer.Order referenziert einen LinkedList die String
Objekte enthält.
LinkedList$...
28
Der Immediate Dominator von LinkedList$Entry2 ist LinkedList$Entry0.
LinkedList$Entry1 ist kein Dominator von LinkedLis...
29
Durch die immediate Dominator‘s wird ein Baum aufgespannt (== Dominator tree).
30
Das com.myerp.buyer.Order Objekt „domiert die 3 String Objekte. Das heißt, dass wenn man diese
Objekt aus dem Speicher ...
31
Wichtige Funktionen
Dominator Tree
Immediate Dominators
Top Consumers
32
33
Im Eclipse Debugger kann man dies leicht nachvollziehen. Der Grund für dieses Verhalten ist
die effiziente Implementier...
34
Im Eclipse Debugger kann man dies leicht nachvollziehen. Der Grund für dieses Verhalten ist
die effiziente Implementier...
35
Dieses Verhalten ist so gewollt. Der Vorteil ist dass mehrere String Objekte sich ein char[]
teilen können.
36
37
XML DOM Bäume brauchen sehr viel Speicher, und sollten daher nicht direkt als
Datenstruktur verwendet werden.
Wenn der ...
38
Caches sind relativ aufwendig zu implementieren, da nicht nur der Cache selber
implementiert werden muss sonder auch di...
39
Es gibt einige Strategien zur Minimierung des Speicherverbrauchs. Hier nur die wichtigsten.
Der Memory Analyzer bietet ...
40
41
Die Klasse java.util.concurrent.CopyOnWriteArrayList (ab JDK 1.5) verwendet diese
Strategie
42
43
43
44
Nächste SlideShare
Wird geladen in …5
×

Eclipse Memory Analyzer MAJUG November 2008

1.205 Aufrufe

Veröffentlicht am

Slides (handouts with notes)from the MAJUG Talk 2008 for the Eclipse Memory Analyzer

Veröffentlicht in: Technologie
0 Kommentare
2 Gefällt mir
Statistik
Notizen
  • Als Erste(r) kommentieren

Keine Downloads
Aufrufe
Aufrufe insgesamt
1.205
Auf SlideShare
0
Aus Einbettungen
0
Anzahl an Einbettungen
5
Aktionen
Geteilt
0
Downloads
21
Kommentare
0
Gefällt mir
2
Einbettungen 0
Keine Einbettungen

Keine Notizen für die Folie

Eclipse Memory Analyzer MAJUG November 2008

  1. 1. 1
  2. 2. 2
  3. 3. 3
  4. 4. 4 Ein Garbage Collector sorgt dafür dass nur die Objekte dir noch erreichbar sind im Speicher bleiben. Nicht erreichbare Objekte können dem Programm nicht mehr von Nutzen sein und können daher gelöscht werden. Wann der GC Objekte löscht ist typischerweise nicht determiniert. Dies steht im Gegensatz zu Reference Counting, dass z.B. in C++ gerne als einfache automatische Speicherverwaltung genutzt wird.
  5. 5. 5 Malloc muss normalerweise eine Liste freier Speicherbereiche verwalten ->Malloc typischerweise langsamer als ein new in Java
  6. 6. 6 Das eigentliche Problem sind die versteckten Kosten des GC. Praktisch jede GC Implementierung erfordert eine „stop the world“ Phase, bei der alle Applikationsthreads angehalten werden müssen. Der Benutzer hat dann den Eindruck einer nicht vorhersagbaren Antwortzeit.
  7. 7. 7 „Normaler“ Garbage Collector log http://www.tagtraum.com/gcviewer.html Der Speicherverbrauchstrend zeigt keinen Anstieg. Daher liegt hier wohl kein Memory Leak vor Je kleiner der Speicherverbrauch nach einem Full GC ist desto weniger Full GC‘s müssen bei sonst gleichen Bedinungen ausgeführt werden
  8. 8. 8
  9. 9. 9 Shallow size == flache Grösse des Objektes. Die Shallow Size ist in der Praxis ein nützliches Maß für den Overhead eines Objektes. „object header“ : Jedes Java Object (in der SUN/SAP JVM) hat einen Header, der Informationen über das Object Layout, Type, GC Zustand, Synchronization Status, und identity hash code enthält. Der Object header ist 2 Worte (8Bytes unter 32 bit) groß.
  10. 10. 10 Man beachte : Mehrere Stringobjekte können das gleiche char[] verwenden (sharing) Selbst ein leerer String braucht mehr als 24 bytes wenn das leere char[] nicht gemeinsam verwendet wird.
  11. 11. 11 Diese Werte beziehen sich auf eine SUN JVM für 32 bit Intel Prozessoren. Bei anderen JVM‘s oder anderen Prozessoren kann der Speicherverbrauch anders aussehen.
  12. 12. 12 Unter 64 bit braucht eine Java Applikation signifikant mehr Speicher als unter 32 bit, weil Referenzen 8 Byte statt 4 Byte benötigen. Der Unterschied im Speicherverbrauch hängt daher vor allem davon ab wieviele Referenzen es gibt. Bei identischer Hardware (Speichergröße) bringt der Übergang auf 64 bit daher zunächst oft keinen Performancegewinn. Allerdings ist unter 32 Bit Windows die maximale Größe des Java Heaps auf nicht viel mehr als 1 Gbyte beschränkt (etwas mehr unter Linux und bis zu 3,8 Gbyte unter Solaris).
  13. 13. 13 In diesem vereinfachten Beispiel können folgende Schlüsse aus den Daten gezogen werden : Es wird am meisten Speicher in char[] verbraucht Die Anzahl der String Objekte ist etwas kleiner als die der char[]. Es wird aus den Daten nicht klar ob die vielen String Objekte char[] „sharen Es ist nicht klar ob möglicherweise com.erp.Order viele Stringobjekte referenziert und dadurch letztlich den hohen Speicherverbrauch verursacht
  14. 14. 14 Da die shallow size in der Praxis nicht sehr nützlich ist, braucht man ein Maß für die Menge des Speichers die festgehalten wird. Dazu simuliert man einen GC Lauf unter der Annahme, das eine bestimme Menge von Objekten nicht mehr existieren würde.
  15. 15. 15 Hier ist ein Beispiel der LinkedList Klasse aus dem JDK dargestellt
  16. 16. 16
  17. 17. 17
  18. 18. 18 Ein Heap Dump ist ein File, dass alle „noch lebendenden“ Java Objekte zu einem bestimmten Zeitpunkt enthält. „Noch lebenden“= Erreichbar Genaugenommen kann ein Heap dump auch noch Objekte enthalten, die nicht mehr referenziert werden. Im Allgemeinen werden diese Objekte von den gängigen Heap dump Analyse Tools allerdings nicht betrachtet. Vor einem Heap dump wird ein Full GC ausgelöst.
  19. 19. 19 Dies gilt zumindest für die SUN/SAP JVM. Andere JVM‘S (IBM) schreiben Heap Dumps, die einige Informationen nicht enthalten
  20. 20. 20 Es gibt einige verschiedene Möglichkeiten einen Heap dump zu erzeugen
  21. 21. 21 Die Option
  22. 22. 22
  23. 23. 23 Das IBM Heap Dump Format wird durch ein zusätzliches Plugin unterstützt MAT kann sowohl standalone als auch innerhalb von Eclipse benutzt werden
  24. 24. 24 Wichtige Funktionen Class histogramm Show object Retained size Retained set
  25. 25. 25
  26. 26. 26 Objekte mit großer retained Size in einem großen Heap Dump mit Millionen von Objekten zu finden ist manuell sehr schwierig. Ein naiver Algorithmus um die größten Objekte zu finden,könnte für jedes Objekt im Heap eine Simulation einer Garbage Collection durchführen. Dies würde allerdings O(n^2) Aufwand bedeuten. Nimmt man z.B. 5 Sekunden für eine GC Simulation an und hat einen Heap mit 10 Millionen Objekten so bräuchte man mit diesem Algorithmus schon mehr als 1,5 Jahre. Außerdem hätte man damit noch nicht die Information über die immediate Dominatoren der Objekte. Der durch die immediate Dominatoren aufgespannte „Dominator tree“ erlaubt es unter anderem die retained Size aller Objekte vorzuberechnen und der Größe nach zu sortieren. Der Dominator Tree kann in „fast“ O(n) (O(m*agr;(m, n); agr == Inversion der Ackermannfunktion) Zeit mit dem Lengauer Tarjan Algorithmus (http://portal.acm.org/citation.cfm?id=357071&dl=GUIDE,) berechnet werden.
  27. 27. 27 Das Business Objekt vom Typ com.myerp.buyer.Order referenziert einen LinkedList die String Objekte enthält. LinkedList$Entry2 ist der immediate Dominator von String 2
  28. 28. 28 Der Immediate Dominator von LinkedList$Entry2 ist LinkedList$Entry0. LinkedList$Entry1 ist kein Dominator von LinkedList$Entry2, da beim Entfernen von LinkedList$Entry 1 weiterhin eine Referenz von LinkedList$Entry0 auf LinkedList$Entry 2 besteht.
  29. 29. 29 Durch die immediate Dominator‘s wird ein Baum aufgespannt (== Dominator tree).
  30. 30. 30 Das com.myerp.buyer.Order Objekt „domiert die 3 String Objekte. Das heißt, dass wenn man diese Objekt aus dem Speicher entfernen würde dann würde der GC auch die 3 Strings freigeben. Daß sich dazwischen eine Java Collection Klasse befindet ist für die Analyse meist nicht von Interesse. Es kann daher nützlich sein im Dominator Tree Knoten herauszufiltern. Typischerweise möchte man Instanzen von Java Standard library Klassen herausfiltern.
  31. 31. 31 Wichtige Funktionen Dominator Tree Immediate Dominators Top Consumers
  32. 32. 32
  33. 33. 33 Im Eclipse Debugger kann man dies leicht nachvollziehen. Der Grund für dieses Verhalten ist die effiziente Implementierung von StringBuffer.toString(). Diese kopiert nämlich das interne char[] des StringBuffer‘s nicht sondern verwendet es für den neu erzeugten String (unter JDK 1.4).
  34. 34. 34 Im Eclipse Debugger kann man dies leicht nachvollziehen. Der Grund für dieses Verhalten ist die effiziente Implementierung von StringBuffer.toString(). Diese kopiert nämlich das interne char[] des StringBuffer‘s nicht sondern verwendet es für den neu erzeugten String (unter JDK 1.4).
  35. 35. 35 Dieses Verhalten ist so gewollt. Der Vorteil ist dass mehrere String Objekte sich ein char[] teilen können.
  36. 36. 36
  37. 37. 37 XML DOM Bäume brauchen sehr viel Speicher, und sollten daher nicht direkt als Datenstruktur verwendet werden. Wenn der XML Parser alte Daten referenziert wird unnötig Speicher verbraucht. XSLT Transformerobjekte können mehrere Mbyte verbrauchen. Da die Transformerobjekte relativ teuer zu erzeugen sind kann man durch Pooling versuchen immer nur einen begrenzte Zahl im Speicher zu halten.
  38. 38. 38 Caches sind relativ aufwendig zu implementieren, da nicht nur der Cache selber implementiert werden muss sonder auch die Infrastruktur zum Monitoring und zur Administration. Daher sollte man auf eine existierende stabile Cacheimplementierung zurückgreifen. Ist eine Webseite „stateless“, kann also der Inhalt der Seite nur aus den Parametern des Request berechnet werden, so kann sie auch gut vom Browser gecached werden.
  39. 39. 39 Es gibt einige Strategien zur Minimierung des Speicherverbrauchs. Hier nur die wichtigsten. Der Memory Analyzer bietet z.B. Queries für das finden leerer Collections an.
  40. 40. 40
  41. 41. 41 Die Klasse java.util.concurrent.CopyOnWriteArrayList (ab JDK 1.5) verwendet diese Strategie
  42. 42. 42
  43. 43. 43 43
  44. 44. 44

×