OOM m'a tuer - Devoxx France 2012

Post on 01-Jul-2015

6,929 views 1 download

description

By Frank Pavageau and Renaud Bruyeron

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