SlideShare une entreprise Scribd logo
Guide de survie du
développeur 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
• Développeur 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 d’exécution
BreizhCamp 2016 #BzhCmp@blep
Collecter des données
sur l'environnement
concerné!
BreizhCamp 2016 #BzhCmp@blep
Lenteurs
avec 1 utilisateur?
Ouvrir un shell sur la
plateforme d’exécution
CPU
bound?
GC?
BreizhCamp 2016 #BzhCmp@blep
Les problèmes liés à la
mémoire
• 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 class
http://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 façon concurrente
BreizhCamp 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
• Gère la heap en zones discrètes
• Phases:
1. Initial Mark (STW)
2. Root Region Scanning
3. Concurrent Marking
4. Remark (STW)
5. Cleanup / Copying
Eden
Survi
vor
Old
Old
EdenEden
Old
Survi
vor
OldEden Eden
BreizhCamp 2016 #BzhCmp@blep
Le log du GC
90,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/GCViewer
BreizhCamp 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 d’exécution
CPU
bound?
GC?
Prélever 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
String
B i l lvalue:
4/8o
Group
name:
4/8o
a d m i n
group:
4/8o
User
age: 42
8o
group:
4/8o
name:
4/8o
String
J o h nvalue:
4/8o
Shallow size
Retained 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 d’exécution
CPU
bound?
GC?
Prélever un heap dump
Fuite
ou utilisation
abusive?
Analyser le dump et
identifier les dominateurs
Augmenter la mémoire
Optimisation du code
BreizhCamp 2016 #BzhCmp@blep
Et le tuning mémoire et GC?
• Définition des ratios pour tailler les zones Eden, Survivor et Old
• Définition d’objectifs de latence
• Nombre de threads alloués 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 d’exécution
CPU
bound?
GC?
Prélever un heap dump
Fuite
ou utilisation
abusive?
Analyser le dump et
identifier les dominateurs
Augmenter la mémoire
Prélever un ou plusieurs
thread dumps
OU
Analyser l’activité 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 <0x00000007a53d8a00> (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 <0x00000007a53d7910> (a org.hsqldb.ClientConnection)
at org.hsqldb.ClientConnection.getAttribute(Unknown Source)
- locked <0x00000007a53d7910> (a org.hsqldb.ClientConnection)
at org.hsqldb.ClientConnection.isAutoCommit(Unknown Source)
- locked <0x00000007a53d7910> (a org.hsqldb.ClientConnection)
at org.hsqldb.jdbc.JDBCConnection.getAutoCommit(Unknown Source)
- locked <0x00000007a53d75f0> (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 <0x00000007a7be3e38> (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 l’attente de l’acquisition d’un moniteur pour entrer dans un
bloc synchronisé
• La synchronisation d’un bloc permet de garantir que les instructions ne sont exécutées
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 monitor
Thread2 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 <0x00000006c0012178> (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.<init>(String.java:534)
at java.lang.String.<init>(String.java:554)
at blep.LockTest.intenseLockingComputation(LockTest.java:39)
- locked <0x00000006c0012178> (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 exécute 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 <0x00000007b11190c0> (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 <0x00000007a060c310> (a java.io.BufferedOutputStream)
at java.io.PrintStream.write(PrintStream.java:480)
- locked <0x00000007a060c2f0> (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 <0x00000007b11190c0> (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 Analyzer
http://the-babel-tower.github.io/tda.html
Analyse des moniteurs
soumis à concurrence
Stats
Recherche dans les
piles d’appels
Lien vers GrepCode (enfin
quand ça marche…)
Regroupements par état
BreizhCamp 2016 #BzhCmp@blep
Thread history
BreizhCamp 2016 #BzhCmp@blep
Ca dépend !
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 RUN12
WAIT1
RUN21 RUN22
WAIT2
Conception séquentielle
et bloquante
Conception non bloquante
basée 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 dépend!
• Batch: autant que de threads physiques
• Transactionnel : plus (à voire avec la charge et la
proportion d’attente)
BreizhCamp 2016 #BzhCmp@blep
Tester
Lenteurs
avec 1 utilisateur?
Ouvrir un shell sur la
plateforme d’exécution
CPU
bound?
GC?
Prélever un heap dump
Fuite
ou utilisation
abusive?
Analyser le dump et
identifier les dominateurs
Augmenter la mémoire
Prélever un ou plusieurs
thread dumps
OU
Analyser l’activité des
threads avec un profiler
Identifier les segments de
code applicatifs concernés
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
• Télémétrie
• Léger
• Profilers payants:
• Coût décent (500/600€)
• Peu de choix
• Performants
• Précis
• Sondes de haut niveau
• Intégrés à l’IDE
BreizhCamp 2016 #BzhCmp@blep
Tester
Lenteurs
avec 1 utilisateur?
Ouvrir un shell sur la
plateforme d’exécution
CPU
bound?
GC?
Prélever un heap dump
Fuite
ou utilisation
abusive?
Analyser le dump et
identifier les dominateurs
Augmenter la mémoire
Prélever un ou plusieurs
thread dumps
OU
Analyser l’activité des
threads avec un profiler
Identifier les segments de
code applicatifs concernés
Optimisation du code
Locks?
Identifier les moniteurs
soumis à concurrence
IO
bound?
Analyser l’activité 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 d’exécution
CPU
bound?
GC?
Prélever un heap dump
Fuite
ou utilisation
abusive?
Analyser le dump et
identifier les dominateurs
Augmenter la mémoire
Prélever un ou plusieurs
thread dumps
OU
Analyser l’activité des
threads avec un profiler
Identifier les segments de
code applicatifs concernés
Optimisation du code
Locks?
Identifier les moniteurs
soumis à concurrence
IO
bound?
Analyser l’activité I/O
Optimiser les IO (cache?)
BreizhCamp 2016 #BzhCmp@blep
Tester
Lenteurs
avec 1 utilisateur?
Ouvrir un shell sur la
plateforme d’exécution
CPU
bound?
GC?
Prélever un heap dump
Fuite
ou utilisation
abusive?
Analyser le dump et
identifier les dominateurs
Augmenter la mémoire
Prélever un ou plusieurs
thread dumps
OU
Analyser l’activité des
threads avec un profiler
Identifier les segments de
code applicatifs concernés
Optimisation du code
Locks?
Identifier les moniteurs
soumis à concurrence
IO
bound?
Analyser l’activité I/O
Optimiser les IO (cache?)
Prélever 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 requêtes HTTP?
• initial = max = maxIdle !
Expérimenter pour réduire le temps d’acquisition et
obtenir la meilleure cadence
BreizhCamp 2016 #BzhCmp@blep
Tester
Pool sous
dimensionné?
Redimensionner
Lenteurs
avec 1 utilisateur?
Ouvrir un shell sur la
plateforme d’exécution
CPU
bound?
GC?
Prélever un heap dump
Fuite
ou utilisation
abusive?
Analyser le dump et
identifier les dominateurs
Augmenter la mémoire
Prélever un ou plusieurs
thread dumps
OU
Analyser l’activité des
threads avec un profiler
Identifier les segments de
code applicatifs concernés
Optimisation du code
Locks?
Identifier les moniteurs
soumis à concurrence
IO
bound?
Analyser l’activité I/O
Optimiser les IO (cache?)
Prélever un ou plusieurs
thread dumps
pour identifier les threads
en wait
BreizhCamp 2016 #BzhCmp@blep
Tester
Pool sous
dimensionné?
Redimensionner
Analyser l’activité/l’utilisation
des systèmes externes
Lenteurs
avec 1 utilisateur?
Ouvrir un shell sur la
plateforme d’exécution
CPU
bound?
GC?
Prélever un heap dump
Fuite
ou utilisation
abusive?
Analyser le dump et
identifier les dominateurs
Augmenter la mémoire
Prélever un ou plusieurs
thread dumps
OU
Analyser l’activité des
threads avec un profiler
Identifier les segments de
code applicatifs concernés
Optimisation du code
Locks?
Identifier les moniteurs
soumis à concurrence
IO
bound?
Analyser l’activité I/O
Optimiser les IO (cache?)
Prélever un ou plusieurs
thread dumps
pour identifier les threads
en wait
BreizhCamp 2016 #BzhCmp@blep
Always blame the database!
• Analyse des plans d’exécution / query trace
• Ajout d’indexes
• Fraîcheur des statistiques
• Purge de données / partitionnement / sharding
(NoSQL)
• Rationalisation des échanges (batches, round trips,
fetch size)
• Dénormalisation
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 l’activité/l’utilisation
des systèmes externes
Optimiser les IO (batches /
buffers / …?)
Lenteurs
avec 1 utilisateur?
Ouvrir un shell sur la
plateforme d’exécution
CPU
bound?
GC?
Prélever un heap dump
Fuite
ou utilisation
abusive?
Analyser le dump et
identifier les dominateurs
Augmenter la mémoire
Prélever un ou plusieurs
thread dumps
OU
Analyser l’activité des
threads avec un profiler
Identifier les segments de
code applicatifs concernés
Optimisation du code
Locks?
Identifier les moniteurs
soumis à concurrence
IO
bound?
Analyser l’activité I/O
Optimiser les IO (cache?)
Prélever un ou plusieurs
thread dumps
pour identifier les threads
en wait
BreizhCamp 2016 #BzhCmp@blep
Et la virtualisation?
• Réservation de ressources!
BreizhCamp 2016 #BzhCmp@blep
https://www.youtube.com/watch?v=XK2sG7AiEY8
Optimisation du code
Identifier les segments de
code applicatifs concernés
Tester
Pool sous
dimensionné?
Redimensionner
Analyser l’activité/l’utilisation
des systèmes externes
Optimiser les IO (batches /
buffers / …?)
Lenteurs
avec 1 utilisateur?
Ouvrir un shell sur la
plateforme d’exécution
CPU
bound?
GC?
Prélever un heap dump
Fuite
ou utilisation
abusive?
Analyser le dump et
identifier les dominateurs
Augmenter la mémoire
Prélever un ou plusieurs
thread dumps
OU
Analyser l’activité des
threads avec un profiler
Identifier les segments de
code applicatifs concernés
Optimisation du code
Locks?
Identifier les moniteurs
soumis à concurrence
CPU
bound?
Placer des marqueurs de
mesure dans les log
OU
Analyser l’activité avec un
profiler
IO
bound?
Analyser l’activité I/O
Optimiser les IO (cache?)
Tester
Prélever un ou plusieurs
thread dumps
pour identifier les threads
en wait
BreizhCamp 2016 #BzhCmp@blep
Faites confiance aux
frameworks matures!
BreizhCamp 2016 #BzhCmp@blep

Contenu connexe

Tendances

Introduction au langage Go
Introduction au langage GoIntroduction au langage Go
Introduction au langage Go
Sylvain Wallez
 
Stockage et analyse temps réel d'événements avec Riak chez Booking.com
Stockage et analyse temps réel d'événements avec Riak chez Booking.comStockage et analyse temps réel d'événements avec Riak chez Booking.com
Stockage et analyse temps réel d'événements avec Riak chez Booking.com
Damien Krotkine
 
EBIZNEXT-RIAK
EBIZNEXT-RIAKEBIZNEXT-RIAK
EBIZNEXT-RIAKebiznext
 
Paris RailsCamp 2009
Paris RailsCamp 2009Paris RailsCamp 2009
Paris RailsCamp 2009
Olivier Gutknecht
 
Ajax et Accessibilite
Ajax et AccessibiliteAjax et Accessibilite
Ajax et Accessibilitemikeh
 
Cassandra Ippevent 20 Juin 2013
Cassandra Ippevent 20 Juin 2013Cassandra Ippevent 20 Juin 2013
Cassandra Ippevent 20 Juin 2013
vberetti
 
Realtime Web avec Kafka, Spark et Mesos
Realtime Web avec Kafka, Spark et MesosRealtime Web avec Kafka, Spark et Mesos
Realtime Web avec Kafka, Spark et Mesosebiznext
 
Guide (un tout petit peu) pratique (et totalement subjectif) du stream proces...
Guide (un tout petit peu) pratique (et totalement subjectif) du stream proces...Guide (un tout petit peu) pratique (et totalement subjectif) du stream proces...
Guide (un tout petit peu) pratique (et totalement subjectif) du stream proces...
Bruno Bonnin
 
Ajax - GTI780 & MTI780 - ETS - A08
Ajax - GTI780 & MTI780 - ETS - A08Ajax - GTI780 & MTI780 - ETS - A08
Ajax - GTI780 & MTI780 - ETS - A08
Claude Coulombe
 
Usages autour d’Ansible chez ikoula
Usages autour d’Ansible chez ikoulaUsages autour d’Ansible chez ikoula
Usages autour d’Ansible chez ikoula
Nicolas Trauwaen
 
Présentation Ansible Ikoula
Présentation Ansible IkoulaPrésentation Ansible Ikoula
Présentation Ansible Ikoula
Ikoula
 
Guss webcasts Query Memory Grants - june 2013
Guss webcasts   Query Memory Grants - june 2013Guss webcasts   Query Memory Grants - june 2013
Guss webcasts Query Memory Grants - june 2013
David BAFFALEUF
 
Déploiement de Silverpeas sur JOnAS
Déploiement de Silverpeas sur JOnASDéploiement de Silverpeas sur JOnAS
Déploiement de Silverpeas sur JOnASAlexis Hassler
 
Android rendu et performance - 17 avril 2012
Android rendu et performance - 17 avril 2012Android rendu et performance - 17 avril 2012
Android rendu et performance - 17 avril 2012Paris Android User Group
 
Javascript : fondamentaux et OOP
Javascript : fondamentaux et OOPJavascript : fondamentaux et OOP
Javascript : fondamentaux et OOP
Jean-Pierre Vincent
 
L'avenir de LAMP
L'avenir de LAMPL'avenir de LAMP
L'avenir de LAMP
Damien Seguy
 
Audit Applications Javaee Solutions Linux Ow2
Audit Applications Javaee Solutions Linux Ow2Audit Applications Javaee Solutions Linux Ow2
Audit Applications Javaee Solutions Linux Ow2Catherine Nuel
 
HTML5 en projet
HTML5 en projetHTML5 en projet
HTML5 en projet
Normandy JUG
 

Tendances (19)

Introduction au langage Go
Introduction au langage GoIntroduction au langage Go
Introduction au langage Go
 
Stockage et analyse temps réel d'événements avec Riak chez Booking.com
Stockage et analyse temps réel d'événements avec Riak chez Booking.comStockage et analyse temps réel d'événements avec Riak chez Booking.com
Stockage et analyse temps réel d'événements avec Riak chez Booking.com
 
EBIZNEXT-RIAK
EBIZNEXT-RIAKEBIZNEXT-RIAK
EBIZNEXT-RIAK
 
Paris RailsCamp 2009
Paris RailsCamp 2009Paris RailsCamp 2009
Paris RailsCamp 2009
 
Ajax et Accessibilite
Ajax et AccessibiliteAjax et Accessibilite
Ajax et Accessibilite
 
Cassandra Ippevent 20 Juin 2013
Cassandra Ippevent 20 Juin 2013Cassandra Ippevent 20 Juin 2013
Cassandra Ippevent 20 Juin 2013
 
Realtime Web avec Kafka, Spark et Mesos
Realtime Web avec Kafka, Spark et MesosRealtime Web avec Kafka, Spark et Mesos
Realtime Web avec Kafka, Spark et Mesos
 
Guide (un tout petit peu) pratique (et totalement subjectif) du stream proces...
Guide (un tout petit peu) pratique (et totalement subjectif) du stream proces...Guide (un tout petit peu) pratique (et totalement subjectif) du stream proces...
Guide (un tout petit peu) pratique (et totalement subjectif) du stream proces...
 
Ajax - GTI780 & MTI780 - ETS - A08
Ajax - GTI780 & MTI780 - ETS - A08Ajax - GTI780 & MTI780 - ETS - A08
Ajax - GTI780 & MTI780 - ETS - A08
 
Usages autour d’Ansible chez ikoula
Usages autour d’Ansible chez ikoulaUsages autour d’Ansible chez ikoula
Usages autour d’Ansible chez ikoula
 
Présentation Ansible Ikoula
Présentation Ansible IkoulaPrésentation Ansible Ikoula
Présentation Ansible Ikoula
 
Guss webcasts Query Memory Grants - june 2013
Guss webcasts   Query Memory Grants - june 2013Guss webcasts   Query Memory Grants - june 2013
Guss webcasts Query Memory Grants - june 2013
 
Spring Batch ParisJUG
Spring Batch ParisJUG Spring Batch ParisJUG
Spring Batch ParisJUG
 
Déploiement de Silverpeas sur JOnAS
Déploiement de Silverpeas sur JOnASDéploiement de Silverpeas sur JOnAS
Déploiement de Silverpeas sur JOnAS
 
Android rendu et performance - 17 avril 2012
Android rendu et performance - 17 avril 2012Android rendu et performance - 17 avril 2012
Android rendu et performance - 17 avril 2012
 
Javascript : fondamentaux et OOP
Javascript : fondamentaux et OOPJavascript : fondamentaux et OOP
Javascript : fondamentaux et OOP
 
L'avenir de LAMP
L'avenir de LAMPL'avenir de LAMP
L'avenir de LAMP
 
Audit Applications Javaee Solutions Linux Ow2
Audit Applications Javaee Solutions Linux Ow2Audit Applications Javaee Solutions Linux Ow2
Audit Applications Javaee Solutions Linux Ow2
 
HTML5 en projet
HTML5 en projetHTML5 en projet
HTML5 en projet
 

Similaire à Breizhcamp : Guide de survie du développeur dans une application (Java) qui rame

gRPC, échange à haute fréquence!
gRPC, échange à haute fréquence!gRPC, échange à haute fréquence!
gRPC, échange à haute fréquence!
David Caramelo
 
gRPC, ECHANGES A HAUTE FREQUENCE !
gRPC, ECHANGES A HAUTE FREQUENCE !gRPC, ECHANGES A HAUTE FREQUENCE !
gRPC, ECHANGES A HAUTE FREQUENCE !
Carles Sistare
 
Développer sereinement avec Node.js
Développer sereinement avec Node.jsDévelopper sereinement avec Node.js
Développer sereinement avec Node.js
Julien Giovaresco
 
Pytong2015
Pytong2015Pytong2015
Mesurer la performance dans le milieu hostile du développement Java
Mesurer la performance dans le milieu hostile du développement JavaMesurer la performance dans le milieu hostile du développement Java
Mesurer la performance dans le milieu hostile du développement Java
Antonio Gomes Rodrigues
 
SQL Debug avec Django @ PyConFr 2015
SQL Debug avec Django @ PyConFr 2015SQL Debug avec Django @ PyConFr 2015
SQL Debug avec Django @ PyConFr 2015
Rodolphe Quiédeville
 
Codedarmor 2012 - 06/03 - HTML5, CSS3 et Javascript
Codedarmor 2012 - 06/03 - HTML5, CSS3 et JavascriptCodedarmor 2012 - 06/03 - HTML5, CSS3 et Javascript
Codedarmor 2012 - 06/03 - HTML5, CSS3 et Javascript
codedarmor
 
Introduction aux RIA (Rich Internet Applications)
Introduction aux RIA (Rich Internet Applications)Introduction aux RIA (Rich Internet Applications)
Introduction aux RIA (Rich Internet Applications)
Tugdual Grall
 
Ou sont mes beans, contrats et workflows ? WOA et REST: Un changement de ment...
Ou sont mes beans, contrats et workflows ? WOA et REST: Un changement de ment...Ou sont mes beans, contrats et workflows ? WOA et REST: Un changement de ment...
Ou sont mes beans, contrats et workflows ? WOA et REST: Un changement de ment...Jean-Laurent de Morlhon
 
Methodologie et outils d optimisation php mysql
Methodologie et outils d optimisation php mysqlMethodologie et outils d optimisation php mysql
Methodologie et outils d optimisation php mysql
Codizy
 
Un navigateur, comment ça marche
Un navigateur, comment ça marche  Un navigateur, comment ça marche
Un navigateur, comment ça marche
Mouhamadou Moustapha CAMARA
 
ParisJUG-2022-v0.4.pdf
ParisJUG-2022-v0.4.pdfParisJUG-2022-v0.4.pdf
ParisJUG-2022-v0.4.pdf
Jean-Francois James
 
RennesJS Talk webperf by Dareboost
RennesJS Talk webperf by DareboostRennesJS Talk webperf by Dareboost
RennesJS Talk webperf by Dareboost
Damien Jubeau
 
Morning tech #2 - Démarche performance slides
Morning tech #2 - Démarche performance slidesMorning tech #2 - Démarche performance slides
Morning tech #2 - Démarche performance slides
Oxalide
 
Oxalide Morning tech #2 - démarche performance
Oxalide Morning tech #2 - démarche performanceOxalide Morning tech #2 - démarche performance
Oxalide Morning tech #2 - démarche performance
Ludovic Piot
 
Stream processing et SQL
Stream processing et SQLStream processing et SQL
Stream processing et SQL
Bruno Bonnin
 
Déploiement ELK en conditions réelles
Déploiement ELK en conditions réellesDéploiement ELK en conditions réelles
Déploiement ELK en conditions réelles
Geoffroy Arnoud
 
Gatling Tool in Action at DevoxxFR 2012
Gatling Tool in Action at DevoxxFR 2012Gatling Tool in Action at DevoxxFR 2012
Gatling Tool in Action at DevoxxFR 2012
slandelle
 
Introduction à Angularjs
Introduction à AngularjsIntroduction à Angularjs
Introduction à Angularjs
Rossi Oddet
 
Hibernate.pdf
Hibernate.pdfHibernate.pdf
Hibernate.pdf
AbdellatifDev
 

Similaire à Breizhcamp : Guide de survie du développeur dans une application (Java) qui rame (20)

gRPC, échange à haute fréquence!
gRPC, échange à haute fréquence!gRPC, échange à haute fréquence!
gRPC, échange à haute fréquence!
 
gRPC, ECHANGES A HAUTE FREQUENCE !
gRPC, ECHANGES A HAUTE FREQUENCE !gRPC, ECHANGES A HAUTE FREQUENCE !
gRPC, ECHANGES A HAUTE FREQUENCE !
 
Développer sereinement avec Node.js
Développer sereinement avec Node.jsDévelopper sereinement avec Node.js
Développer sereinement avec Node.js
 
Pytong2015
Pytong2015Pytong2015
Pytong2015
 
Mesurer la performance dans le milieu hostile du développement Java
Mesurer la performance dans le milieu hostile du développement JavaMesurer la performance dans le milieu hostile du développement Java
Mesurer la performance dans le milieu hostile du développement Java
 
SQL Debug avec Django @ PyConFr 2015
SQL Debug avec Django @ PyConFr 2015SQL Debug avec Django @ PyConFr 2015
SQL Debug avec Django @ PyConFr 2015
 
Codedarmor 2012 - 06/03 - HTML5, CSS3 et Javascript
Codedarmor 2012 - 06/03 - HTML5, CSS3 et JavascriptCodedarmor 2012 - 06/03 - HTML5, CSS3 et Javascript
Codedarmor 2012 - 06/03 - HTML5, CSS3 et Javascript
 
Introduction aux RIA (Rich Internet Applications)
Introduction aux RIA (Rich Internet Applications)Introduction aux RIA (Rich Internet Applications)
Introduction aux RIA (Rich Internet Applications)
 
Ou sont mes beans, contrats et workflows ? WOA et REST: Un changement de ment...
Ou sont mes beans, contrats et workflows ? WOA et REST: Un changement de ment...Ou sont mes beans, contrats et workflows ? WOA et REST: Un changement de ment...
Ou sont mes beans, contrats et workflows ? WOA et REST: Un changement de ment...
 
Methodologie et outils d optimisation php mysql
Methodologie et outils d optimisation php mysqlMethodologie et outils d optimisation php mysql
Methodologie et outils d optimisation php mysql
 
Un navigateur, comment ça marche
Un navigateur, comment ça marche  Un navigateur, comment ça marche
Un navigateur, comment ça marche
 
ParisJUG-2022-v0.4.pdf
ParisJUG-2022-v0.4.pdfParisJUG-2022-v0.4.pdf
ParisJUG-2022-v0.4.pdf
 
RennesJS Talk webperf by Dareboost
RennesJS Talk webperf by DareboostRennesJS Talk webperf by Dareboost
RennesJS Talk webperf by Dareboost
 
Morning tech #2 - Démarche performance slides
Morning tech #2 - Démarche performance slidesMorning tech #2 - Démarche performance slides
Morning tech #2 - Démarche performance slides
 
Oxalide Morning tech #2 - démarche performance
Oxalide Morning tech #2 - démarche performanceOxalide Morning tech #2 - démarche performance
Oxalide Morning tech #2 - démarche performance
 
Stream processing et SQL
Stream processing et SQLStream processing et SQL
Stream processing et SQL
 
Déploiement ELK en conditions réelles
Déploiement ELK en conditions réellesDéploiement ELK en conditions réelles
Déploiement ELK en conditions réelles
 
Gatling Tool in Action at DevoxxFR 2012
Gatling Tool in Action at DevoxxFR 2012Gatling Tool in Action at DevoxxFR 2012
Gatling Tool in Action at DevoxxFR 2012
 
Introduction à Angularjs
Introduction à AngularjsIntroduction à Angularjs
Introduction à Angularjs
 
Hibernate.pdf
Hibernate.pdfHibernate.pdf
Hibernate.pdf
 

Dernier

Le Comptoir OCTO - Qu’apporte l’analyse de cycle de vie lors d’un audit d’éco...
Le Comptoir OCTO - Qu’apporte l’analyse de cycle de vie lors d’un audit d’éco...Le Comptoir OCTO - Qu’apporte l’analyse de cycle de vie lors d’un audit d’éco...
Le Comptoir OCTO - Qu’apporte l’analyse de cycle de vie lors d’un audit d’éco...
OCTO Technology
 
Le Comptoir OCTO - Équipes infra et prod, ne ratez pas l'embarquement pour l'...
Le Comptoir OCTO - Équipes infra et prod, ne ratez pas l'embarquement pour l'...Le Comptoir OCTO - Équipes infra et prod, ne ratez pas l'embarquement pour l'...
Le Comptoir OCTO - Équipes infra et prod, ne ratez pas l'embarquement pour l'...
OCTO Technology
 
Le support de présentation des Signaux 2024
Le support de présentation des Signaux 2024Le support de présentation des Signaux 2024
Le support de présentation des Signaux 2024
UNITECBordeaux
 
De l'IA comme plagiat à la rédaction d'une « charte IA » à l'université
De l'IA comme plagiat à la rédaction d'une « charte IA » à l'universitéDe l'IA comme plagiat à la rédaction d'une « charte IA » à l'université
De l'IA comme plagiat à la rédaction d'une « charte IA » à l'université
Université de Franche-Comté
 
OCTO TALKS : 4 Tech Trends du Software Engineering.pdf
OCTO TALKS : 4 Tech Trends du Software Engineering.pdfOCTO TALKS : 4 Tech Trends du Software Engineering.pdf
OCTO TALKS : 4 Tech Trends du Software Engineering.pdf
OCTO Technology
 
Ouvrez la porte ou prenez un mur (Agile Tour Genève 2024)
Ouvrez la porte ou prenez un mur (Agile Tour Genève 2024)Ouvrez la porte ou prenez un mur (Agile Tour Genève 2024)
Ouvrez la porte ou prenez un mur (Agile Tour Genève 2024)
Laurent Speyser
 

Dernier (6)

Le Comptoir OCTO - Qu’apporte l’analyse de cycle de vie lors d’un audit d’éco...
Le Comptoir OCTO - Qu’apporte l’analyse de cycle de vie lors d’un audit d’éco...Le Comptoir OCTO - Qu’apporte l’analyse de cycle de vie lors d’un audit d’éco...
Le Comptoir OCTO - Qu’apporte l’analyse de cycle de vie lors d’un audit d’éco...
 
Le Comptoir OCTO - Équipes infra et prod, ne ratez pas l'embarquement pour l'...
Le Comptoir OCTO - Équipes infra et prod, ne ratez pas l'embarquement pour l'...Le Comptoir OCTO - Équipes infra et prod, ne ratez pas l'embarquement pour l'...
Le Comptoir OCTO - Équipes infra et prod, ne ratez pas l'embarquement pour l'...
 
Le support de présentation des Signaux 2024
Le support de présentation des Signaux 2024Le support de présentation des Signaux 2024
Le support de présentation des Signaux 2024
 
De l'IA comme plagiat à la rédaction d'une « charte IA » à l'université
De l'IA comme plagiat à la rédaction d'une « charte IA » à l'universitéDe l'IA comme plagiat à la rédaction d'une « charte IA » à l'université
De l'IA comme plagiat à la rédaction d'une « charte IA » à l'université
 
OCTO TALKS : 4 Tech Trends du Software Engineering.pdf
OCTO TALKS : 4 Tech Trends du Software Engineering.pdfOCTO TALKS : 4 Tech Trends du Software Engineering.pdf
OCTO TALKS : 4 Tech Trends du Software Engineering.pdf
 
Ouvrez la porte ou prenez un mur (Agile Tour Genève 2024)
Ouvrez la porte ou prenez un mur (Agile Tour Genève 2024)Ouvrez la porte ou prenez un mur (Agile Tour Genève 2024)
Ouvrez la porte ou prenez un mur (Agile Tour Genève 2024)
 

Breizhcamp : Guide de survie du développeur dans une application (Java) qui rame

  • 1. Guide de survie du développeur dans une application (Java) qui rame BreizhCamp 2016 #BzhCmp@blep
  • 2. 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
  • 3. About me • Brice LEPORINI • Développeur Java / Scala BreizhCamp 2016 #BzhCmp@blep http://the-babel-tower.github.io/ @blep
  • 4. Lenteurs ou performance ? BreizhCamp 2016 #BzhCmp@blep
  • 5. Scott Oaks - Java Performance The definitive guide There is no magical -XX:+RunReallyFast option BreizhCamp 2016 #BzhCmp@blep
  • 6. Lenteurs avec 1 utilisateur? Ouvrir un shell sur la plateforme d’exécution BreizhCamp 2016 #BzhCmp@blep
  • 7. Collecter des données sur l'environnement concerné! BreizhCamp 2016 #BzhCmp@blep
  • 8. Lenteurs avec 1 utilisateur? Ouvrir un shell sur la plateforme d’exécution CPU bound? GC? BreizhCamp 2016 #BzhCmp@blep
  • 9. Les problèmes liés à la mémoire • Terminal avec jstat -gcutil BreizhCamp 2016 #BzhCmp@blep
  • 10. 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
  • 11. GC: la master class http://www.infoq.com/presentations/Understanding-Java-Garbage-Collection BreizhCamp 2016 #BzhCmp@blep
  • 12. Les GC Stop The World • Serial GC: 1 thread • Throughput Collector ou Parallel Collector: • multi threads young et old BreizhCamp 2016 #BzhCmp@blep
  • 13. 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 façon concurrente BreizhCamp 2016 #BzhCmp@blep
  • 14. 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 • Gère la heap en zones discrètes • Phases: 1. Initial Mark (STW) 2. Root Region Scanning 3. Concurrent Marking 4. Remark (STW) 5. Cleanup / Copying Eden Survi vor Old Old EdenEden Old Survi vor OldEden Eden BreizhCamp 2016 #BzhCmp@blep
  • 15. Le log du GC 90,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
  • 17. Maintenant qu'on en sait un peu plus sur les GC, lequel choisir? BreizhCamp 2016 #BzhCmp@blep
  • 18. Profils applicatifs • Transactionnels • Batches BreizhCamp 2016 #BzhCmp@blep
  • 19. Choix du GC • Batch: • Throughtput collector • Application transactionnelle: • GC concurrent • CMS heap < 4GB • G1 heap >= 4GB BreizhCamp 2016 #BzhCmp@blep
  • 20. Lenteurs avec 1 utilisateur? Ouvrir un shell sur la plateforme d’exécution CPU bound? GC? Prélever un heap dump BreizhCamp 2016 #BzhCmp@blep
  • 21. 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
  • 22. Retained size et dominateur User age: 42 8o name: 4/8o String B i l lvalue: 4/8o Group name: 4/8o a d m i n group: 4/8o User age: 42 8o group: 4/8o name: 4/8o String J o h nvalue: 4/8o Shallow size Retained size deep size BreizhCamp 2016 #BzhCmp@blep
  • 23. Memory Analyzer Tool (MAT) http://www.eclipse.org/mat/ 1 2 3 BreizhCamp 2016 #BzhCmp@blep
  • 24. Tester Lenteurs avec 1 utilisateur? Ouvrir un shell sur la plateforme d’exécution CPU bound? GC? Prélever un heap dump Fuite ou utilisation abusive? Analyser le dump et identifier les dominateurs Augmenter la mémoire Optimisation du code BreizhCamp 2016 #BzhCmp@blep
  • 25. Et le tuning mémoire et GC? • Définition des ratios pour tailler les zones Eden, Survivor et Old • Définition d’objectifs de latence • Nombre de threads alloués 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
  • 26. Tester Lenteurs avec 1 utilisateur? Ouvrir un shell sur la plateforme d’exécution CPU bound? GC? Prélever un heap dump Fuite ou utilisation abusive? Analyser le dump et identifier les dominateurs Augmenter la mémoire Prélever un ou plusieurs thread dumps OU Analyser l’activité des threads avec un profiler Optimisation du code BreizhCamp 2016 #BzhCmp@blep
  • 27. 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 <0x00000007a53d8a00> (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 <0x00000007a53d7910> (a org.hsqldb.ClientConnection) at org.hsqldb.ClientConnection.getAttribute(Unknown Source) - locked <0x00000007a53d7910> (a org.hsqldb.ClientConnection) at org.hsqldb.ClientConnection.isAutoCommit(Unknown Source) - locked <0x00000007a53d7910> (a org.hsqldb.ClientConnection) at org.hsqldb.jdbc.JDBCConnection.getAutoCommit(Unknown Source) - locked <0x00000007a53d75f0> (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 <0x00000007a7be3e38> (a java.lang.Object) BreizhCamp 2016 #BzhCmp@blep
  • 28. Les états du thread BreizhCamp 2016 #BzhCmp@blep
  • 29. java.lang.Thread.State#BLOCKED • Un thread bloqué est dans l’attente de l’acquisition d’un moniteur pour entrer dans un bloc synchronisé • La synchronisation d’un bloc permet de garantir que les instructions ne sont exécutées 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 monitor Thread2 verrouille monitor BreizhCamp 2016 #BzhCmp@blep
  • 30. 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 <0x00000006c0012178> (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.<init>(String.java:534) at java.lang.String.<init>(String.java:554) at blep.LockTest.intenseLockingComputation(LockTest.java:39) - locked <0x00000006c0012178> (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 exécute la ligne et a verrouillé le moniteur là BreizhCamp 2016 #BzhCmp@blep
  • 31. 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 <0x00000007b11190c0> (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 <0x00000007a060c310> (a java.io.BufferedOutputStream) at java.io.PrintStream.write(PrintStream.java:480) - locked <0x00000007a060c2f0> (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 <0x00000007b11190c0> (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
  • 32. Mon Thread Dump Analyzer http://the-babel-tower.github.io/tda.html Analyse des moniteurs soumis à concurrence Stats Recherche dans les piles d’appels Lien vers GrepCode (enfin quand ça marche…) Regroupements par état BreizhCamp 2016 #BzhCmp@blep
  • 34. Ca dépend ! Dimensionner un pool de threads BreizhCamp 2016 #BzhCmp@blep
  • 35. Sync vs Async RUN RUNWAIT Traitement 2 x Traitement @ 1 thread : RUN11 RUN12WAIT1 RUN21 RUN22WAIT2Sync Async RUN11 RUN12 WAIT1 RUN21 RUN22 WAIT2 Conception séquentielle et bloquante Conception non bloquante basée sur la composition de callbacks BreizhCamp 2016 #BzhCmp@blep
  • 36. Dimensionner un pool de threads • Conception asynchrone: autant que de threads physiques (@see /proc/cpuinfo) • Conception synchrone: ça dépend! • Batch: autant que de threads physiques • Transactionnel : plus (à voire avec la charge et la proportion d’attente) BreizhCamp 2016 #BzhCmp@blep
  • 37. Tester Lenteurs avec 1 utilisateur? Ouvrir un shell sur la plateforme d’exécution CPU bound? GC? Prélever un heap dump Fuite ou utilisation abusive? Analyser le dump et identifier les dominateurs Augmenter la mémoire Prélever un ou plusieurs thread dumps OU Analyser l’activité des threads avec un profiler Identifier les segments de code applicatifs concernés Optimisation du code Locks? Identifier les moniteurs soumis à concurrence BreizhCamp 2016 #BzhCmp@blep
  • 38. Identifier les consommateurs avec un profiler • Sampling ou profiling? BreizhCamp 2016 #BzhCmp@blep
  • 39. Profiler gratuit ou payant? • Profilers gratuits: • Gratuit! • Pas de choix • Peu performant • Télémétrie • Léger • Profilers payants: • Coût décent (500/600€) • Peu de choix • Performants • Précis • Sondes de haut niveau • Intégrés à l’IDE BreizhCamp 2016 #BzhCmp@blep
  • 40. Tester Lenteurs avec 1 utilisateur? Ouvrir un shell sur la plateforme d’exécution CPU bound? GC? Prélever un heap dump Fuite ou utilisation abusive? Analyser le dump et identifier les dominateurs Augmenter la mémoire Prélever un ou plusieurs thread dumps OU Analyser l’activité des threads avec un profiler Identifier les segments de code applicatifs concernés Optimisation du code Locks? Identifier les moniteurs soumis à concurrence IO bound? Analyser l’activité I/O BreizhCamp 2016 #BzhCmp@blep
  • 41. Monitorer les I/O BreizhCamp 2016 #BzhCmp@blep
  • 42. Identifier les contentions I/O BreizhCamp 2016 #BzhCmp@blep
  • 43. Tester Lenteurs avec 1 utilisateur? Ouvrir un shell sur la plateforme d’exécution CPU bound? GC? Prélever un heap dump Fuite ou utilisation abusive? Analyser le dump et identifier les dominateurs Augmenter la mémoire Prélever un ou plusieurs thread dumps OU Analyser l’activité des threads avec un profiler Identifier les segments de code applicatifs concernés Optimisation du code Locks? Identifier les moniteurs soumis à concurrence IO bound? Analyser l’activité I/O Optimiser les IO (cache?) BreizhCamp 2016 #BzhCmp@blep
  • 44. Tester Lenteurs avec 1 utilisateur? Ouvrir un shell sur la plateforme d’exécution CPU bound? GC? Prélever un heap dump Fuite ou utilisation abusive? Analyser le dump et identifier les dominateurs Augmenter la mémoire Prélever un ou plusieurs thread dumps OU Analyser l’activité des threads avec un profiler Identifier les segments de code applicatifs concernés Optimisation du code Locks? Identifier les moniteurs soumis à concurrence IO bound? Analyser l’activité I/O Optimiser les IO (cache?) Prélever un ou plusieurs thread dumps pour identifier les threads en wait BreizhCamp 2016 #BzhCmp@blep
  • 45. Exemple du pool sous dimensionné BreizhCamp 2016 #BzhCmp@blep
  • 46. Dimensionner un pool JDBC • x connexions pour y utilisateurs? • 42? • Autant que de requêtes HTTP? • initial = max = maxIdle ! Expérimenter pour réduire le temps d’acquisition et obtenir la meilleure cadence BreizhCamp 2016 #BzhCmp@blep
  • 47. Tester Pool sous dimensionné? Redimensionner Lenteurs avec 1 utilisateur? Ouvrir un shell sur la plateforme d’exécution CPU bound? GC? Prélever un heap dump Fuite ou utilisation abusive? Analyser le dump et identifier les dominateurs Augmenter la mémoire Prélever un ou plusieurs thread dumps OU Analyser l’activité des threads avec un profiler Identifier les segments de code applicatifs concernés Optimisation du code Locks? Identifier les moniteurs soumis à concurrence IO bound? Analyser l’activité I/O Optimiser les IO (cache?) Prélever un ou plusieurs thread dumps pour identifier les threads en wait BreizhCamp 2016 #BzhCmp@blep
  • 48. Tester Pool sous dimensionné? Redimensionner Analyser l’activité/l’utilisation des systèmes externes Lenteurs avec 1 utilisateur? Ouvrir un shell sur la plateforme d’exécution CPU bound? GC? Prélever un heap dump Fuite ou utilisation abusive? Analyser le dump et identifier les dominateurs Augmenter la mémoire Prélever un ou plusieurs thread dumps OU Analyser l’activité des threads avec un profiler Identifier les segments de code applicatifs concernés Optimisation du code Locks? Identifier les moniteurs soumis à concurrence IO bound? Analyser l’activité I/O Optimiser les IO (cache?) Prélever un ou plusieurs thread dumps pour identifier les threads en wait BreizhCamp 2016 #BzhCmp@blep
  • 49. Always blame the database! • Analyse des plans d’exécution / query trace • Ajout d’indexes • Fraîcheur des statistiques • Purge de données / partitionnement / sharding (NoSQL) • Rationalisation des échanges (batches, round trips, fetch size) • Dénormalisation BreizhCamp 2016 #BzhCmp@blep
  • 50. Optimisation IO • Utiliser les Buffered(In|Out)putStreams • Utilisation de cache: • Applicatif • cache FS du kernel BreizhCamp 2016 #BzhCmp@blep
  • 51. Tester Pool sous dimensionné? Redimensionner Analyser l’activité/l’utilisation des systèmes externes Optimiser les IO (batches / buffers / …?) Lenteurs avec 1 utilisateur? Ouvrir un shell sur la plateforme d’exécution CPU bound? GC? Prélever un heap dump Fuite ou utilisation abusive? Analyser le dump et identifier les dominateurs Augmenter la mémoire Prélever un ou plusieurs thread dumps OU Analyser l’activité des threads avec un profiler Identifier les segments de code applicatifs concernés Optimisation du code Locks? Identifier les moniteurs soumis à concurrence IO bound? Analyser l’activité I/O Optimiser les IO (cache?) Prélever un ou plusieurs thread dumps pour identifier les threads en wait BreizhCamp 2016 #BzhCmp@blep
  • 52. Et la virtualisation? • Réservation de ressources! BreizhCamp 2016 #BzhCmp@blep https://www.youtube.com/watch?v=XK2sG7AiEY8
  • 53. Optimisation du code Identifier les segments de code applicatifs concernés Tester Pool sous dimensionné? Redimensionner Analyser l’activité/l’utilisation des systèmes externes Optimiser les IO (batches / buffers / …?) Lenteurs avec 1 utilisateur? Ouvrir un shell sur la plateforme d’exécution CPU bound? GC? Prélever un heap dump Fuite ou utilisation abusive? Analyser le dump et identifier les dominateurs Augmenter la mémoire Prélever un ou plusieurs thread dumps OU Analyser l’activité des threads avec un profiler Identifier les segments de code applicatifs concernés Optimisation du code Locks? Identifier les moniteurs soumis à concurrence CPU bound? Placer des marqueurs de mesure dans les log OU Analyser l’activité avec un profiler IO bound? Analyser l’activité I/O Optimiser les IO (cache?) Tester Prélever un ou plusieurs thread dumps pour identifier les threads en wait BreizhCamp 2016 #BzhCmp@blep
  • 54. Faites confiance aux frameworks matures! BreizhCamp 2016 #BzhCmp@blep