View
2.008
Download
3
Category
Preview:
Citation preview
Guide de survie du dveloppeur dans une
application (Java) qui rame
@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
@blep
About me
Brice LEPORINI
Dveloppeur Java / Scala
@blep
http://the-babel-tower.github.io/ @blep
Lenteurs ou performance ?
@blep
Scott Oaks - Java Performance The definitive guide
There is no magical -XX:+RunReallyFast option
@blep
Lenteurs avec 1 utilisateur?
Ouvrir un shell sur la plateforme dexcution
@blep
Collecter des donnes sur l'environnement
concern!
@blep
Lenteurs avec 1 utilisateur?
Ouvrir un shell sur la plateforme dexcution
CPU bound? GC?
@blep
Les problmes lis la mmoire
Terminal avec jstat -gcutil
@blep
Young Generation
Heap
Eden
From Space To Space
Old Generation
Survivor
1: new
2: minor 1
3: n minors
4: promotion
@blep
GC: la master classhttp://www.infoq.com/presentations/Understanding-Java-Garbage-Collection
@blep
Les GC Stop The World
Serial GC: 1 thread
Throughput Collector ou Parallel Collector:
multi threads young et old
@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 concurrente@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
@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
@blep
GCViewer
https://github.com/chewiebug/GCViewer@blep
Maintenant qu'on en sait un peu plus sur les GC,
lequel choisir?
@blep
Profils applicatifs
Transactionnels
Batches
@blep
Choix du GC Batch:
Throughtput collector
Application transactionnelle:
GC concurrent
CMS heap < 4GB
G1 heap >= 4GB
@blep
Lenteurs avec 1 utilisateur?
Ouvrir un shell sur la plateforme dexcution
CPU bound? GC?
Prlever un heap dump
@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 ...
@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
@blep
Memory Analyzer Tool (MAT)
http://www.eclipse.org/mat/
1
2
3
@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
@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
@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
@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)
@blep
Les tats du thread
@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
@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
@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)
@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
@blep
Thread history
@blep
Ca dpend !
Dimensionner un pool de threads
@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
@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)
@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
@blep
Identifier les consommateurs avec un profiler
Sampling ou profiling?
@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 lIDE@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
@blep
Monitorer les I/O
@blep
Identifier les contentions I/O
@blep
Optimisation IO
Utilisation de cache:
Applicatif
cache FS du kernel
@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?)
@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
@blep
Exemple du pool sous dimensionn
@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
@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
@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
@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
@blep
Optimisation IO
Utiliser les Buffered(In|Out)putStreams
@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
@blep
Et la virtualisation? Rservation de ressources!
@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
@blep
Recommended