breizhcamp : guide de survie du développeur dans une application (java) qui rame
TRANSCRIPT
-
Guide de survie du dveloppeur dans une
application (Java) qui rame
BreizhCamp 2016 #BzhCmp@blep
-
Les ordres de grandeur importent
Salaire: 1000 --> 1300
Page speed: 30s --> 20s Seuls les changements d'ordre de grandeur
( >300%) changent la perception de la performance de l'application
BreizhCamp 2016 #BzhCmp@blep
-
About me
Brice LEPORINI
Dveloppeur Java / Scala
BreizhCamp 2016 #BzhCmp@blep
http://the-babel-tower.github.io/ @blep
-
Lenteurs ou performance ?
BreizhCamp 2016 #BzhCmp@blep
-
Scott Oaks - Java Performance The definitive guide
There is no magical -XX:+RunReallyFast option
BreizhCamp 2016 #BzhCmp@blep
-
Lenteurs avec 1 utilisateur?
Ouvrir un shell sur la plateforme dexcution
BreizhCamp 2016 #BzhCmp@blep
-
Collecter des donnes sur l'environnement
concern!
BreizhCamp 2016 #BzhCmp@blep
-
Lenteurs avec 1 utilisateur?
Ouvrir un shell sur la plateforme dexcution
CPU bound? GC?
BreizhCamp 2016 #BzhCmp@blep
-
Les problmes lis la mmoire
Terminal avec jstat -gcutil
BreizhCamp 2016 #BzhCmp@blep
-
Young Generation
Heap
Eden
From Space To Space
Old Generation
Survivor
1: new
2: minor 1
3: n minors
4: promotion
BreizhCamp 2016 #BzhCmp@blep
-
GC: la master classhttp://www.infoq.com/presentations/Understanding-Java-Garbage-Collection
BreizhCamp 2016 #BzhCmp@blep
-
Les GC Stop The World
Serial GC: 1 thread
Throughput Collector ou Parallel Collector:
multi threads young et old
BreizhCamp 2016 #BzhCmp@blep
-
Les GC concurrents: CMS Concurrent Mark Sweep
Multi thread sur la young et les phases concurrentes, mono thread sur les Full GC
STW sur les minor GC
6 Phases:
1. Initial mark (STW)
2. Concurrent Mark
3. Pre clean
4. Remark (STW)
5. Sweep
6. Reset
Ne compacte pas de faon concurrenteBreizhCamp 2016 #BzhCmp@blep
-
Les GC concurrents : G1 G1 pour Garbage first
Multi thread sur la young et les phases concurrentes, mono thread sur les Full GC
STW sur les minor GC
Gre la heap en zones discrtes
Phases:
1. Initial Mark (STW)
2. Root Region Scanning
3. Concurrent Marking
4. Remark (STW)
5. Cleanup / Copying
Eden Survivor
Old
Old
EdenEden
Old
Survivor
OldEden Eden
BreizhCamp 2016 #BzhCmp@blep
-
Le log du GC90,652: [ GC (Allocation Failure) [ PSYoungGen: 130768K->1088K(152576K) ] 381293K->253237K(502272K), 0,0044329 secs ] [Times: user=0,02 sys=0,00, real=0,01 secs]
101,003: [ Full GC (Ergonomics) [ PSYoungGen: 3687K->0K(150528K) ] [ ParOldGen: 344000K->132146K(349696K) ] 347687K->132146K(500224K), [ Metaspace: 76887K->76887K(1118208K) ], 0,1998650 secs ] [Times: user=1,03 sys=0,01, real=0,20 secs]
Type de collecte-XX:+PrintGCDetails -XX:+PrintGCTimeStamps -Xloggc:gc.log -XX:+UseGCLogFileRotation -XX:NumberOfGClogFiles=10 -XX:GCLogFileSize=1000K
BreizhCamp 2016 #BzhCmp@blep
-
GCViewer
https://github.com/chewiebug/GCViewerBreizhCamp 2016 #BzhCmp@blep
-
Maintenant qu'on en sait un peu plus sur les GC,
lequel choisir?
BreizhCamp 2016 #BzhCmp@blep
-
Profils applicatifs
Transactionnels
Batches
BreizhCamp 2016 #BzhCmp@blep
-
Choix du GC Batch:
Throughtput collector
Application transactionnelle:
GC concurrent
CMS heap < 4GB
G1 heap >= 4GB
BreizhCamp 2016 #BzhCmp@blep
-
Lenteurs avec 1 utilisateur?
Ouvrir un shell sur la plateforme dexcution
CPU bound? GC?
Prlever un heap dump
BreizhCamp 2016 #BzhCmp@blep
-
Heap dump
$ jmap -dump:file=heap.hprof,format=b,live 4695 Dumping heap to heap.hprof ... Heap dump file created $ du -sh heap.hprof 462M heap.hprof
$ java -XX:+HeapDumpOnOutOfMemoryError \ -XX:HeapDumpPath=myApp.hprof ...
BreizhCamp 2016 #BzhCmp@blep
-
Retained size et dominateur
User
age: 42 8o
name: 4/8o
StringB i l lvalue:
4/8o
Groupname:
4/8oa d m i n
group: 4/8o
User
age: 42 8o
group: 4/8o
name: 4/8o
StringJ o h nvalue:
4/8o
Shallow sizeRetained size deep size
BreizhCamp 2016 #BzhCmp@blep
-
Memory Analyzer Tool (MAT)
http://www.eclipse.org/mat/
1
2
3
BreizhCamp 2016 #BzhCmp@blep
-
Tester
Lenteurs avec 1 utilisateur?
Ouvrir un shell sur la plateforme dexcution
CPU bound? GC?
Prlever un heap dump
Fuite ou utilisation
abusive?
Analyser le dump et identifier les dominateurs
Augmenter la mmoire
Optimisation du code
BreizhCamp 2016 #BzhCmp@blep
-
Et le tuning mmoire et GC?
Dfinition des ratios pour tailler les zones Eden, Survivor et Old
Dfinition dobjectifs de latence
Nombre de threads allous au GC
Java Ergonomics depuis 1.5 -XX:+UseAdaptiveSizePolicy
$ java -XX:+PrintFlagsFinal -version |wc -l java version "1.8.0_66" Java(TM) SE Runtime Environment (build 1.8.0_66-b17) Java HotSpot(TM) 64-Bit Server VM (build 25.66-b17, mixed mode) 718
BreizhCamp 2016 #BzhCmp@blep
-
Tester
Lenteurs avec 1 utilisateur?
Ouvrir un shell sur la plateforme dexcution
CPU bound? GC?
Prlever un heap dump
Fuite ou utilisation
abusive?
Analyser le dump et identifier les dominateurs
Augmenter la mmoire
Prlever un ou plusieurs thread dumps
OU Analyser lactivit des
threads avec un profiler
Optimisation du code
BreizhCamp 2016 #BzhCmp@blep
-
Thread dump$ jstack 4695
2016-03-06 09:47:03 Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.66-b17 mixed mode):
"http-bio-8081-exec-74" #305 daemon prio=5 os_prio=31 tid=0x00007fa2de53b000 nid=0xf11f runnable [0x00000001202e7000] java.lang.Thread.State: RUNNABLE at java.net.SocketInputStream.socketRead0(Native Method) at java.net.SocketInputStream.socketRead(SocketInputStream.java:116) at java.net.SocketInputStream.read(SocketInputStream.java:170) at java.net.SocketInputStream.read(SocketInputStream.java:141) at java.io.BufferedInputStream.fill(BufferedInputStream.java:246) at java.io.BufferedInputStream.read(BufferedInputStream.java:265) - locked (a java.io.BufferedInputStream) at java.io.DataInputStream.readByte(DataInputStream.java:265) at org.hsqldb.result.Result.newResult(Unknown Source) at org.hsqldb.ClientConnection.read(Unknown Source) at org.hsqldb.ClientConnection.execute(Unknown Source) - locked (a org.hsqldb.ClientConnection) at org.hsqldb.ClientConnection.getAttribute(Unknown Source) - locked (a org.hsqldb.ClientConnection) at org.hsqldb.ClientConnection.isAutoCommit(Unknown Source) - locked (a org.hsqldb.ClientConnection) at org.hsqldb.jdbc.JDBCConnection.getAutoCommit(Unknown Source) - locked (a org.hsqldb.jdbc.JDBCConnection) at org.apache.commons.dbcp.DelegatingConnection.getAutoCommit(DelegatingConnection.java:337) []
"http-bio-8081-exec-79" #310 daemon prio=5 os_prio=31 tid=0x00007fa2e00e7800 nid=0xe30b waiting for monitor entry [0x0000000123aa0000] java.lang.Thread.State: BLOCKED (on object monitor) at ch.qos.logback.core.OutputStreamAppender.subAppend(OutputStreamAppender.java:216) - waiting to lock (a java.lang.Object)
BreizhCamp 2016 #BzhCmp@blep
-
Les tats du thread
BreizhCamp 2016 #BzhCmp@blep
-
java.lang.Thread.State#BLOCKED
Un thread bloqu est dans lattente de lacquisition dun moniteur pour entrer dans un bloc synchronis
La synchronisation dun bloc permet de garantir que les instructions ne sont excutes exclusivement que par un et un seul thread
@Test public void lockMe() throws InterruptedException { final Thread thread1 = new Thread(this::intenseLockingComputation); final Thread thread2 = new Thread(this::intenseLockingComputation); thread1.start(); thread2.start();
thread2.join();
}
private final Object monitor = new Object();
private String intenseLockingComputation() { synchronized (monitor) { return { ... } } }
Thread1 verrouille monitor
Thread2 attend monitorThread2 verrouille monitor
BreizhCamp 2016 #BzhCmp@blep
-
Lire le thread dump
"Thread-2" #21 prio=5 os_prio=31 tid=0x00007fed9c8b3800 nid=0x6803 waiting for monitor entry [0x000000012d3b1000] java.lang.Thread.State: BLOCKED (on object monitor) at blep.LockTest.intenseLockingComputation(LockTest.java:36) - waiting to lock (a java.lang.Object) at blep.LockTest$$Lambda$9/204349222.run(Unknown Source) at java.lang.Thread.run(Thread.java:745)
"Thread-1" #20 prio=5 os_prio=31 tid=0x00007fed9bb03000 nid=0x6603 runnable [0x000000012d2ae000] java.lang.Thread.State: RUNNABLE at sun.nio.cs.UTF_8$Decoder.decode(UTF_8.java:456) at java.lang.StringCoding$StringDecoder.decode(StringCoding.java:153) at java.lang.StringCoding.decode(StringCoding.java:193) at java.lang.StringCoding.decode(StringCoding.java:254) at java.lang.String.(String.java:534) at java.lang.String.(String.java:554) at blep.LockTest.intenseLockingComputation(LockTest.java:39) - locked (a java.lang.Object) at blep.LockTest$$Lambda$8/1100439041.run(Unknown Source) at java.lang.Thread.run(Thread.java:745)
Thread-2 est bloqu l en attente du moniteur de la classe
Thread-1 excute la ligne et a verrouill le moniteur l
BreizhCamp 2016 #BzhCmp@blep
-
Un cas concret de verrouillage"http-bio-8081-exec-172" #454 daemon prio=5 os_prio=31 tid=0x00007fa2e00f2000 nid=0xe12f waiting for monitor entry [0x0000000122acc000] java.lang.Thread.State: BLOCKED (on object monitor) at ch.qos.logback.core.OutputStreamAppender.subAppend(OutputStreamAppender.java:216) - waiting to lock (a java.lang.Object) at ch.qos.logback.core.OutputStreamAppender.append(OutputStreamAppender.java:108) at ch.qos.logback.core.UnsynchronizedAppenderBase.doAppend(UnsynchronizedAppenderBase.java:88) at ch.qos.logback.core.spi.AppenderAttachableImpl.appendLoopOnAppenders(AppenderAttachableImpl.java:64) at ch.qos.logback.classic.Logger.appendLoopOnAppenders(Logger.java:285) at ch.qos.logback.classic.Logger.callAppenders(Logger.java:272) at ch.qos.logback.classic.Logger.buildLoggingEventAndAppend(Logger.java:473) at ch.qos.logback.classic.Logger.filterAndLog_0_Or3Plus(Logger.java:427) at ch.qos.logback.classic.Logger.debug(Logger.java:534)
"http-bio-8081-exec-173" #457 daemon prio=5 os_prio=31 tid=0x00007fa2e275e800 nid=0xf61b runnable [0x0000000122de8000] java.lang.Thread.State: RUNNABLE at java.io.FileOutputStream.writeBytes(Native Method) at java.io.FileOutputStream.write(FileOutputStream.java:326) at java.io.BufferedOutputStream.write(BufferedOutputStream.java:122) - locked (a java.io.BufferedOutputStream) at java.io.PrintStream.write(PrintStream.java:480) - locked (a java.io.PrintStream) at java.io.FilterOutputStream.write(FilterOutputStream.java:97) at org.apache.tomcat.util.log.SystemLogHandler.write(SystemLogHandler.java:169) at ch.qos.logback.core.joran.spi.ConsoleTarget$1.write(ConsoleTarget.java:36) at ch.qos.logback.core.encoder.LayoutWrappingEncoder.doEncode(LayoutWrappingEncoder.java:103) at ch.qos.logback.core.OutputStreamAppender.writeOut(OutputStreamAppender.java:193) at ch.qos.logback.core.OutputStreamAppender.subAppend(OutputStreamAppender.java:217) - locked (a java.lang.Object) at ch.qos.logback.core.OutputStreamAppender.append(OutputStreamAppender.java:108) at ch.qos.logback.core.UnsynchronizedAppenderBase.doAppend(UnsynchronizedAppenderBase.java:88) at ch.qos.logback.core.spi.AppenderAttachableImpl.appendLoopOnAppenders(AppenderAttachableImpl.java:64)
BreizhCamp 2016 #BzhCmp@blep
-
Mon Thread Dump Analyzerhttp://the-babel-tower.github.io/tda.html
Analyse des moniteurs soumis concurrence
Stats
Recherche dans les piles dappels
Lien vers GrepCode (enfin quand a marche)
Regroupements par tat
BreizhCamp 2016 #BzhCmp@blep
-
Thread history
BreizhCamp 2016 #BzhCmp@blep
-
Ca dpend !
Dimensionner un pool de threads
BreizhCamp 2016 #BzhCmp@blep
-
Sync vs Async
RUN RUNWAIT
Traitement
2 x Traitement @ 1 thread :
RUN11 RUN12WAIT1 RUN21 RUN22WAIT2Sync
Async RUN11 RUN12WAIT1
RUN21 RUN22
WAIT2
Conception squentielle et bloquante
Conception non bloquante base sur la composition de callbacks
BreizhCamp 2016 #BzhCmp@blep
-
Dimensionner un pool de threads
Conception asynchrone: autant que de threads physiques (@see /proc/cpuinfo)
Conception synchrone: a dpend!
Batch: autant que de threads physiques
Transactionnel : plus ( voire avec la charge et la proportion dattente)
BreizhCamp 2016 #BzhCmp@blep
-
Tester
Lenteurs avec 1 utilisateur?
Ouvrir un shell sur la plateforme dexcution
CPU bound? GC?
Prlever un heap dump
Fuite ou utilisation
abusive?
Analyser le dump et identifier les dominateurs
Augmenter la mmoire
Prlever un ou plusieurs thread dumps
OU Analyser lactivit des
threads avec un profiler
Identifier les segments de code applicatifs concerns
Optimisation du code
Locks?
Identifier les moniteurs soumis concurrence
BreizhCamp 2016 #BzhCmp@blep
-
Identifier les consommateurs avec un profiler
Sampling ou profiling?
BreizhCamp 2016 #BzhCmp@blep
-
Profiler gratuit ou payant? Profilers gratuits:
Gratuit!
Pas de choix
Peu performant
Tlmtrie
Lger
Profilers payants:
Cot dcent (500/600)
Peu de choix
Performants
Prcis
Sondes de haut niveau
Intgrs lIDEBreizhCamp 2016 #BzhCmp@blep
-
Tester
Lenteurs avec 1 utilisateur?
Ouvrir un shell sur la plateforme dexcution
CPU bound? GC?
Prlever un heap dump
Fuite ou utilisation
abusive?
Analyser le dump et identifier les dominateurs
Augmenter la mmoire
Prlever un ou plusieurs thread dumps
OU Analyser lactivit des
threads avec un profiler
Identifier les segments de code applicatifs concerns
Optimisation du code
Locks?
Identifier les moniteurs soumis concurrence
IO bound?
Analyser lactivit I/O
BreizhCamp 2016 #BzhCmp@blep
-
Monitorer les I/O
BreizhCamp 2016 #BzhCmp@blep
-
Identifier les contentions I/O
BreizhCamp 2016 #BzhCmp@blep
-
Tester
Lenteurs avec 1 utilisateur?
Ouvrir un shell sur la plateforme dexcution
CPU bound? GC?
Prlever un heap dump
Fuite ou utilisation
abusive?
Analyser le dump et identifier les dominateurs
Augmenter la mmoire
Prlever un ou plusieurs thread dumps
OU Analyser lactivit des
threads avec un profiler
Identifier les segments de code applicatifs concerns
Optimisation du code
Locks?
Identifier les moniteurs soumis concurrence
IO bound?
Analyser lactivit I/O
Optimiser les IO (cache?)
BreizhCamp 2016 #BzhCmp@blep
-
Tester
Lenteurs avec 1 utilisateur?
Ouvrir un shell sur la plateforme dexcution
CPU bound? GC?
Prlever un heap dump
Fuite ou utilisation
abusive?
Analyser le dump et identifier les dominateurs
Augmenter la mmoire
Prlever un ou plusieurs thread dumps
OU Analyser lactivit des
threads avec un profiler
Identifier les segments de code applicatifs concerns
Optimisation du code
Locks?
Identifier les moniteurs soumis concurrence
IO bound?
Analyser lactivit I/O
Optimiser les IO (cache?)
Prlever un ou plusieurs thread dumps
pour identifier les threads en wait
BreizhCamp 2016 #BzhCmp@blep
-
Exemple du pool sous dimensionn
BreizhCamp 2016 #BzhCmp@blep
-
Dimensionner un pool JDBC
x connexions pour y utilisateurs?
42?
Autant que de requtes HTTP?
initial = max = maxIdle !
Exprimenter pour rduire le temps dacquisition et obtenir la meilleure cadence
BreizhCamp 2016 #BzhCmp@blep
-
Tester
Pool sous dimensionn?
Redimensionner
Lenteurs avec 1 utilisateur?
Ouvrir un shell sur la plateforme dexcution
CPU bound? GC?
Prlever un heap dump
Fuite ou utilisation
abusive?
Analyser le dump et identifier les dominateurs
Augmenter la mmoire
Prlever un ou plusieurs thread dumps
OU Analyser lactivit des
threads avec un profiler
Identifier les segments de code applicatifs concerns
Optimisation du code
Locks?
Identifier les moniteurs soumis concurrence
IO bound?
Analyser lactivit I/O
Optimiser les IO (cache?)
Prlever un ou plusieurs thread dumps
pour identifier les threads en wait
BreizhCamp 2016 #BzhCmp@blep
-
Tester
Pool sous dimensionn?
Redimensionner
Analyser lactivit/lutilisation des systmes externes
Lenteurs avec 1 utilisateur?
Ouvrir un shell sur la plateforme dexcution
CPU bound? GC?
Prlever un heap dump
Fuite ou utilisation
abusive?
Analyser le dump et identifier les dominateurs
Augmenter la mmoire
Prlever un ou plusieurs thread dumps
OU Analyser lactivit des
threads avec un profiler
Identifier les segments de code applicatifs concerns
Optimisation du code
Locks?
Identifier les moniteurs soumis concurrence
IO bound?
Analyser lactivit I/O
Optimiser les IO (cache?)
Prlever un ou plusieurs thread dumps
pour identifier les threads en wait
BreizhCamp 2016 #BzhCmp@blep
-
Always blame the database! Analyse des plans dexcution / query trace
Ajout dindexes
Fracheur des statistiques
Purge de donnes / partitionnement / sharding (NoSQL)
Rationalisation des changes (batches, round trips, fetch size)
Dnormalisation
BreizhCamp 2016 #BzhCmp@blep
-
Optimisation IO
Utiliser les Buffered(In|Out)putStreams
Utilisation de cache:
Applicatif
cache FS du kernel
BreizhCamp 2016 #BzhCmp@blep
-
Tester
Pool sous dimensionn?
Redimensionner
Analyser lactivit/lutilisation des systmes externes
Optimiser les IO (batches / buffers / ?)
Lenteurs avec 1 utilisateur?
Ouvrir un shell sur la plateforme dexcution
CPU bound? GC?
Prlever un heap dump
Fuite ou utilisation
abusive?
Analyser le dump et identifier les dominateurs
Augmenter la mmoire
Prlever un ou plusieurs thread dumps
OU Analyser lactivit des
threads avec un profiler
Identifier les segments de code applicatifs concerns
Optimisation du code
Locks?
Identifier les moniteurs soumis concurrence
IO bound?
Analyser lactivit I/O
Optimiser les IO (cache?)
Prlever un ou plusieurs thread dumps
pour identifier les threads en wait
BreizhCamp 2016 #BzhCmp@blep
-
Et la virtualisation? Rservation de ressources!
BreizhCamp 2016 #BzhCmp@blep
https://www.youtube.com/watch?v=XK2sG7AiEY8
-
Optimisation du code
Identifier les segments de code applicatifs concerns
Tester
Pool sous dimensionn?
Redimensionner
Analyser lactivit/lutilisation des systmes externes
Optimiser les IO (batches / buffers / ?)
Lenteurs avec 1 utilisateur?
Ouvrir un shell sur la plateforme dexcution
CPU bound? GC?
Prlever un heap dump
Fuite ou utilisation
abusive?
Analyser le dump et identifier les dominateurs
Augmenter la mmoire
Prlever un ou plusieurs thread dumps
OU Analyser lactivit des
threads avec un profiler
Identifier les segments de code applicatifs concerns
Optimisation du code
Locks?
Identifier les moniteurs soumis concurrence
CPU bound?
Placer des marqueurs de mesure dans les log
OU Analyser lactivit avec un
profiler
IO bound?
Analyser lactivit I/O
Optimiser les IO (cache?)
Tester
Prlever un ou plusieurs thread dumps
pour identifier les threads en wait
BreizhCamp 2016 #BzhCmp@blep
-
Faites confiance aux frameworks matures!
BreizhCamp 2016 #BzhCmp@blep