Post on 01-Jul-2015
description
transcript
Renaud Bruyeron @brew_your_ownFrank Pavageau @fpavageau
1
OOM m’a tuer
Monday, April 23, 12
Agenda
1. La scène du crime
2. La gestion de la mémoire dans la JVM: les bases, les outils
3. Application
2Monday, April 23, 12
• Débuts au
• C -> Perl -> PHP -> Java
Renaud Bruyeron @brew_your_own
3
CTO d’
Monday, April 23, 12
• Débuts au
• C -> Perl -> PHP -> Java
Renaud Bruyeron @brew_your_own
3
CTO d’
Monday, April 23, 12
• C++ -> PHP -> Java
• Systèmes et devops
• Tech Lead socle eCommerce
Frank Pavageau @fpavageau
4
Architecte Senior
Monday, April 23, 12
• C++ -> PHP -> Java
• Systèmes et devops
• Tech Lead socle eCommerce
Frank Pavageau @fpavageau
4
Architecte Senior
Monday, April 23, 12
5
Apa
che
Tom
cat
Ora
cle
Une Plateforme webe-commerce B2C
Monday, April 23, 12
5
Apa
che
Tom
cat
Ora
cle
Une Plateforme webe-commerce B2C
•12+ Serveurs•10 Webapps différentes•50+ JVMs Oracle (JDK6)
Monday, April 23, 12
5
Apa
che
Tom
cat
Ora
cle
Une Plateforme webe-commerce B2C
•12+ Serveurs•10 Webapps différentes•50+ JVMs Oracle (JDK6)
•> 30000 sessions•250-400 Req/s•Variance très importante du trafic
Monday, April 23, 12
... une victime un peu atypique...
6
Modélisation du catalogue sous forme de GrapheImplémentation custom du moteur de catalogue
100% sur la Heap (pas de BDD)Mise à jour par AtomicReference.set()
Monday, April 23, 12
... une victime un peu atypique...
6
Modélisation du catalogue sous forme de GrapheImplémentation custom du moteur de catalogue
100% sur la Heap (pas de BDD)Mise à jour par AtomicReference.set()
Impossible de “cacher” aggressivementBeaucoup d’objets créés à chaque Request
Raccordements SI = latence = concurrence élevée
Monday, April 23, 12
7
vs.
Débit Latence
Monday, April 23, 12
8Monday, April 23, 12
8
Application interactive:Il faut privilégier les temps de réponse!
Monday, April 23, 12
Le flagrant délit
9
Temps
Connections JDBC
Monday, April 23, 12
Le flagrant délit
9
Temps
Connections JDBC
Temps
Requêtes/s
Monday, April 23, 12
Le flagrant délit
9
Temps
Connections JDBC
Temps
Requêtes/s
Temps
Threads actifs
Monday, April 23, 12
Le flagrant délit
9
Temps
Connections JDBC
Temps
Requêtes/s
Temps
Threads actifs
Temps
Requêtes en attente (Executor Queue Size)
Monday, April 23, 12
l’explication
10
Taill
e en
MB
1 heure
Heap
Monday, April 23, 12
l’explication
10
Taill
e en
MB
1 heure
Heap
On manque de recul: zoom arrière!
Monday, April 23, 12
l’explication
11
Taill
e en
MB
24 heures
Heap
Monday, April 23, 12
l’explication
11
Taill
e en
MB
24 heures
Heap
Monday, April 23, 12
l’explication
11
Taill
e en
MB
24 heures
Heap
Monday, April 23, 12
0
25
50
75
100
1 heure
l’explication
12
% de temps passé en GC
Taill
e en
MB
1 heure
Heap
Monday, April 23, 12
The usual suspects...
13Monday, April 23, 12
The usual suspects...
• OutOfMemory Heap
13Monday, April 23, 12
The usual suspects...
• OutOfMemory Heap
• OutOfMemory PermGen
13Monday, April 23, 12
The usual suspects...
• OutOfMemory Heap
• OutOfMemory PermGen
• Longues pauses de la JVM
13Monday, April 23, 12
The usual suspects...
• OutOfMemory Heap
• OutOfMemory PermGen
• Longues pauses de la JVM
➡ Sous forte charge = plantage assuré
13Monday, April 23, 12
The usual suspects...
• OutOfMemory Heap
• OutOfMemory PermGen
• Longues pauses de la JVM
➡ Sous forte charge = plantage assuré
13Monday, April 23, 12
The usual suspects...
• OutOfMemory Heap
• OutOfMemory PermGen
• Longues pauses de la JVM
➡ Sous forte charge = plantage assuré
13Monday, April 23, 12
The usual suspects...
• OutOfMemory Heap
• OutOfMemory PermGen
• Longues pauses de la JVM
➡ Sous forte charge = plantage assuré
13
le GC m’a
tuer!!Monday, April 23, 12
Mais ça sert à quoi alors le GC?
14
“Many concurrent algorithms are very easy to write with a GC and totally hard (to down right impossible) using explicit free.”
Cliff Click
Monday, April 23, 12
OK, donc il suffit de régler quelques options...
15Monday, April 23, 12
OK, donc il suffit de régler quelques options...
15
664 options....
Source: Oracle JVM 1.6.0_31 x86_64 server
Monday, April 23, 12
16Monday, April 23, 12
16Monday, April 23, 12
JVM
La mémoire dans la JVM
17
Monday, April 23, 12
JVM
18
Permanent (PermGen) Metadata de classes,Strings internées, etc.
Monday, April 23, 12
Heap
19
Permanent (PermGen)
Les objets
Metadata de classes,Strings internées, etc.
Monday, April 23, 12
20
Young / New
Old / Tenured
Permanent (PermGen)
Monday, April 23, 12
21
Old / Tenured
Eden S0 S1
Permanent (PermGen)
Monday, April 23, 12
Approche générationelle du GC
22
Old
Eden Sur
vivor 0
Surviv
or 1
Monday, April 23, 12
23
Old
Eden Sur
vivor 0
Surviv
or 1
Allocation
Monday, April 23, 12
24
Old
Eden Sur
vivor 0
Surviv
or 1
Monday, April 23, 12
25
Old
Eden Sur
vivor 0
Surviv
or 1
100% = GC!
Monday, April 23, 12
26
Old
Eden Sur
vivor 0
Surviv
or 1
RéférencéMort
Monday, April 23, 12
27
Old
Eden Sur
vivor 0
Surviv
or 1
Copie
Monday, April 23, 12
Remise à zéro...
28
Old
Eden Sur
vivor 0
Surviv
or 1
Monday, April 23, 12
29
Old
Eden Sur
vivor 0
Surviv
or 1
Allocation
Monday, April 23, 12
30
Old
Eden Sur
vivor 0
Surviv
or 1
100% = GC !
Monday, April 23, 12
31
Old
Eden Sur
vivor 0
Surviv
or 1
Monday, April 23, 12
32
Old
Eden Sur
vivor 0
Surviv
or 1
Copie
Monday, April 23, 12
33
Old
Eden Sur
vivor 0
Surviv
or 1
Copie
Monday, April 23, 12
34
Remise à
Old
zéro
Eden Sur
vivor 0
Surviv
or 1
Génération 1
Génération 2
Monday, April 23, 12
35
Old
Eden Sur
vivor 0
Surviv
or 1
Allocation
Monday, April 23, 12
36
Old
Eden Sur
vivor 0
Surviv
or 1
100% = GC !
Monday, April 23, 12
37
Old
Eden Sur
vivor 0
Surviv
or 1
Copie
Monday, April 23, 12
38
Eden Sur
vivor 0
Surviv
or 1
Promotion
Old
Monday, April 23, 12
Old
39Monday, April 23, 12
40
Old“Assez plein” = GC !
Monday, April 23, 12
41Monday, April 23, 12
42Monday, April 23, 12
43
Old
Compaction(optionnelle)
Monday, April 23, 12
44Monday, April 23, 12
Garbage Collectors
45
•Générationnels
• Stop the world!
• Throughput ou Concurrent
Monday, April 23, 12
Combinaisons de GCs
46
YoungYoung
OldOldOld
Serial Parallel
Serial
Parallel
Concurrent
Monday, April 23, 12
Combinaisons de GCs
47
YoungYoung
OldOldOld
Serial Parallel
Serial Par défaut
Parallel N/A
Concurrent
Monday, April 23, 12
Combinaisons de GCs
48
YoungYoung
OldOldOld
Serial Parallel
Serial
Parallel
Concurrent
Monday, April 23, 12
Combinaisons de GCs
48
YoungYoung
OldOldOld
Serial Parallel
Serial
Parallel
Concurrent
Serial
Monday, April 23, 12
Combinaisons de GCs
48
YoungYoung
OldOldOld
Serial Parallel
Serial
Parallel
Concurrent
Serial Parallel
Monday, April 23, 12
Combinaisons de GCs
48
YoungYoung
OldOldOld
Serial Parallel
Serial
Parallel
Concurrent
Serial Parallel
ParallelOld
Monday, April 23, 12
Combinaisons de GCs
48
YoungYoung
OldOldOld
Serial Parallel
Serial
Parallel
Concurrent
Serial Parallel
ParallelOld
CMS
Monday, April 23, 12
Combinaisons de GCs
48
YoungYoung
OldOldOld
Serial Parallel
Serial
Parallel
Concurrent
Serial Parallel
ParallelOld
CMSCMS Serial
Monday, April 23, 12
Combinaisons de GCs
49
YoungYoung
OldOldOld
Serial Parallel
Serial Serial Parallel
Parallel ParallelOld
Concurrent CMS Serial CMS
Les implémentations de Parallel diffèrent suivant les combinaisons
Monday, April 23, 12
Comparatif des GCs
50Monday, April 23, 12
Comparatif des GCs
50Monday, April 23, 12
CMS est le bon compromis
51
Serial
Parallel
ParallelOld
CMS
CMS Serial
0 250 500 750 1000
937
871
846
852
917
Durée moyenne du test (s)
Monday, April 23, 12
Les outils: CLI
52
jps, jhat, jmap, jstack, jstat
$ jstat -gcutil PID S0 S1 E O P YGC YGCT FGC FGCT GCT 0.00 40.88 58.41 18.34 66.65 2729 316.538 46 6.820 323.358
Monday, April 23, 12
Les outils: GUIs
53Monday, April 23, 12
Les outils: GUIs (2)
•Un profiler
• Pendant le dev
• Pour les autopsies!
54Monday, April 23, 12
Les outils: GUIs (2)
•Un profiler
• Pendant le dev
• Pour les autopsies!
54
HeapDumpOnOutOfMemoryErrorHeapDumpPath
Monday, April 23, 12
verbose:gc
55Monday, April 23, 12
verbose:gc
55Monday, April 23, 12
verbose:gc
55Monday, April 23, 12
verbose:gc
55Monday, April 23, 12
verbose:gc
55Monday, April 23, 12
verbose:gc
55Monday, April 23, 12
verbose:gc
55Monday, April 23, 12
verbose:gc
55
Stop the world!
Monday, April 23, 12
verbose:gc
55
Stop the world!
Monday, April 23, 12
MBeans
56Monday, April 23, 12
OK, donc on sait mesurer... la température!
57Monday, April 23, 12
OK, donc on sait mesurer... la température !
58
=
Monday, April 23, 12
59Credit: http://www.lhup.edu/mkhalequ/fieldtrip/geos253.htm
Problème : on ne peut pas faire un diagnostic avec une simple mesure...
Il faut historiser pour constituer un référentiel !
Monday, April 23, 12
Donc il faut persister les mesures !
• JMX + jmxtrans
• RRD
• Graphite
• etc.
60Monday, April 23, 12
On peut modifier les réglages...
61Credit: http://www.our-energy.com
Monday, April 23, 12
... si on sait mesurer/isoler les effets des réglages
62
Situation “avant”
Effet visible du tuning
cput
ime
Monday, April 23, 12
Application et Résultats
63Monday, April 23, 12
64
Minimiser la fréquence et la durée des pauses de GC
Young (ParNew)Old (CMS-initial-mark + CMS-remark)
Monday, April 23, 12
65
vs.
Monday, April 23, 12
JVM
Tomcat
65
Application(code)
vs.
Monday, April 23, 12
1. Le code
• Le tuning de JVM ne peut pas compenser du code de mauvaise qualité
• Des règles peuvent aider
• Privilégier les données immutables et donc réutilisables sans risque
• Sortir les invariants, notamment les instanciations, et surtout dans les boucles
• Connaitre les caractéristiques des structures de données des frameworks (java.util, Guava, Hibernate, etc.)
• Attention au rapport poids de la structure / poids des données
66Monday, April 23, 12
Exemple : HashMap
67
HashMap
Entry[16]
Entry
value
key
48
80
32
Monday, April 23, 12
Exemple : HashMap
67
HashMap
Entry[16]
Entry
value
key
48
80
32Overhead = 160 Bytes!
Monday, April 23, 12
Exemple : HashMap
67
HashMap
Entry[16]
Entry
value
key
48
80
32Overhead = 160 Bytes!
•SingletonMap (40 Bytes)•initialCapacity + loadFactor
Monday, April 23, 12
Réduire les allocations...
68
GC
You
ng /
s
Monday, April 23, 12
... impacte la CPU
69
Cha
rge
CPU
Monday, April 23, 12
2. Tomcat
• Se méfier du pooling
• Les tags: enablePooling dans web/webdefault.xml
• -Dorg.apache.jasper.runtime.JspFactoryImpl.USE_POOL=false
• Attention aux buffers et à leur réutilisation
• -Dorg.apache.jasper.runtime.BodyContentImpl.LIMIT_BUFFER=true
• Le nombre de JSP impacte les besoins en PermGen
• Faire des tests et mesurer les impacts!
70Monday, April 23, 12
3. La JVM
71
Hea
p Si
ze
Time
Hea
p Si
ze
Time
Monday, April 23, 12
3. La JVM
71
Hea
p Si
ze
Time
Hea
p Si
ze
Time
pause > 1s !
Monday, April 23, 12
3. La JVM
71
Hea
p Si
ze
Time
Hea
p Si
ze
Time
GC très fréquents
pause > 1s !
Monday, April 23, 12
La heap
72
Heap
Monday, April 23, 12
La heap
72
Heap-Xms : taille au démarrage
-Xmx : taille max
Monday, April 23, 12
Young vs Old
73
Young
Old
Monday, April 23, 12
Young vs Old
73
Young
Old
-XX:NewSize -XX:MaxNewSize-XX:NewRatio
Monday, April 23, 12
Young vs Old
73
Young
Old•“Working Set”•Caches, Pools d’objets•HttpSession, objets de durée de vie intermédiaire
Objets < RequestScope
Monday, April 23, 12
Young trop petite:
74
Young
Old
Monday, April 23, 12
Young trop petite:
74
Young
Old
Young se remplit très vite = Beaucoup de GC Young
Promotion excessive d’objets en Old = Beaucoup de GC Old
Monday, April 23, 12
Young trop grande:
75
Young
Old
Monday, April 23, 12
Young trop grande:
75
Young
Old
Pauses de GC Young plus longues
Monday, April 23, 12
Réglage de Young
76
Young
Old
NewRatio=8 pour -server sur Intel=
Trop peu de Young pour une webapp avec de la charge!
Monday, April 23, 12
Réglage de Young
76
Young
Old
On augmente Young progressivement en mesurant les effets!
Monday, April 23, 12
Old: attention à la fragmentation!
77
Young
Old
Monday, April 23, 12
Old: attention à la fragmentation!
77
Young
OldJDK6 < u22:
ParNew (prom
otion failur
e size = 155
95) (promoti
on failed)
Monday, April 23, 12
Old generation : évolution idéale
78Monday, April 23, 12
Old generation : évolution réelle
79Monday, April 23, 12
Old generation : évolutions comparées
80Monday, April 23, 12
Old generation : évolutions comparées
80
Accélérations
Monday, April 23, 12
Contraintes supplémentaires
• Prise en compte des variations irrégulières
• Augmentation de trafic => augmentation de la pression mémoire
• Pour bien fonctionner, CMS doit avoir de la marge
• Plusieurs phases successives, la plupart concurrentes avec l’application=> le remplissage continue en même temps
81Monday, April 23, 12
Contraintes supplémentaires
• Prise en compte des variations irrégulières
• Augmentation de trafic => augmentation de la pression mémoire
• Pour bien fonctionner, CMS doit avoir de la marge
• Plusieurs phases successives, la plupart concurrentes avec l’application=> le remplissage continue en même temps
81
(concurrent mode failure): 2165740K->1284261K(2228224K), 8.9411250 secs
Monday, April 23, 12
Marge de manoeuvre
82
Young
Old
Monday, April 23, 12
Marge de manoeuvre
82
Young
Old
CMSInitiatingOccupancyFraction = 92% par défaut
Monday, April 23, 12
75-80% pour plus de marge
UseCMSInitiatingOccupancyOnly pour forcer le déclenchement uniquement sur ce critère!
Marge de manoeuvre
82
Young
Old
Monday, April 23, 12
83
CMS initial-mark
Monday, April 23, 12
84
CMS initial-mark (cumulé)
Monday, April 23, 12
84
CMS initial-mark (cumulé)
Mediane: -83%
Monday, April 23, 12
84
CMS initial-mark (cumulé)
Mediane: -83%
Top 99%: -79%
Monday, April 23, 12
85
CMS remark
Monday, April 23, 12
86
CMS remark (cumulé)
Monday, April 23, 12
86
CMS remark (cumulé)
Top 90%: -56%
Monday, April 23, 12
Il reste des pauses !
• RMI (donc JMX) provoque des GC explicites à intervalles réguliers
• Appels à System.gc()
• GC explicite = Full GC (Serial) = pause de 4s !
• DisableExplicitGC + CMSClassUnloadingEnabled
• ExplicitGCInvokesConcurrentAndUnloadsClasses
87Monday, April 23, 12
Comparatif complet des GC
88Monday, April 23, 12
89Monday, April 23, 12
89Monday, April 23, 12
• Tuning des Survivors
• Taille, ratio de survivants, age maximum
• G1
• Principes et options complétement différents
• Autres JDKs : JRockit, Azul, IBM
• Vérifier les réglages à chaque changement applicatif
• Mesurer, mesurer, mesurer!
90
Et après?
Monday, April 23, 12
91
Questions ?
Monday, April 23, 12