SlideShare une entreprise Scribd logo
1  sur  54
Télécharger pour lire hors ligne
Guide de survie du
développeur 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
• Développeur 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 d’exécution
@blep
Collecter des données
sur l'environnement
concerné!
@blep
Lenteurs
avec 1 utilisateur?
Ouvrir un shell sur la
plateforme d’exécution
CPU
bound?
GC?
@blep
Les problèmes liés à la
mémoire
• 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 class
http://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 façon 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
• 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
@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
@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 d’exécution
CPU
bound?
GC?
Prélever 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
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
@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 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
@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
@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
@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)
@blep
Les états du thread
@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
@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à
@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)
@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
@blep
Thread history
@blep
Ca dépend !
Dimensionner un pool de
threads
@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
@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)
@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
@blep
Identifier les consommateurs avec un profiler
• Sampling ou profiling?
@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
@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
@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 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?)
@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
@blep
Exemple du pool sous dimensionné
@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
@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
@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
@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
@blep
Optimisation IO
• Utiliser les Buffered(In|Out)putStreams
@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
@blep
Et la virtualisation?
• Réservation de ressources!
@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
@blep

Contenu connexe

Tendances

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.comDamien Krotkine
 
EBIZNEXT-RIAK
EBIZNEXT-RIAKEBIZNEXT-RIAK
EBIZNEXT-RIAKebiznext
 
Cassandra Ippevent 20 Juin 2013
Cassandra Ippevent 20 Juin 2013Cassandra Ippevent 20 Juin 2013
Cassandra Ippevent 20 Juin 2013vberetti
 
Introduction au langage Go
Introduction au langage GoIntroduction au langage Go
Introduction au langage GoSylvain Wallez
 
Spark Streaming
Spark StreamingSpark Streaming
Spark StreamingPALO IT
 
Apache Flink par Bilal Baltagi Paris Spark Meetup Dec 2015
Apache Flink par Bilal Baltagi Paris Spark Meetup Dec 2015Apache Flink par Bilal Baltagi Paris Spark Meetup Dec 2015
Apache Flink par Bilal Baltagi Paris Spark Meetup Dec 2015Modern Data Stack France
 
WS User Group - Spring Batch - Xebia
WS User Group - Spring Batch - XebiaWS User Group - Spring Batch - Xebia
WS User Group - Spring Batch - XebiaOlivier BAZOUD
 
Paris JUG Spring Batch
Paris JUG Spring BatchParis JUG Spring Batch
Paris JUG Spring BatchOlivier BAZOUD
 
Ajax - GTI780 & MTI780 - ETS - A08
Ajax - GTI780 & MTI780 - ETS - A08Ajax - GTI780 & MTI780 - ETS - A08
Ajax - GTI780 & MTI780 - ETS - A08Claude Coulombe
 
Chtijug springbatch 2011
Chtijug springbatch 2011Chtijug springbatch 2011
Chtijug springbatch 2011Olivier BAZOUD
 
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 2013David 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
 
Le futur d'apache cassandra
Le futur d'apache cassandraLe futur d'apache cassandra
Le futur d'apache cassandraDuyhai Doan
 
Spark, ou comment traiter des données à la vitesse de l'éclair
Spark, ou comment traiter des données à la vitesse de l'éclairSpark, ou comment traiter des données à la vitesse de l'éclair
Spark, ou comment traiter des données à la vitesse de l'éclairAlexis Seigneurin
 

Tendances (20)

Riak introduction
Riak introductionRiak introduction
Riak introduction
 
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
 
Cassandra Ippevent 20 Juin 2013
Cassandra Ippevent 20 Juin 2013Cassandra Ippevent 20 Juin 2013
Cassandra Ippevent 20 Juin 2013
 
1 2-3-grails
1 2-3-grails1 2-3-grails
1 2-3-grails
 
Introduction au langage Go
Introduction au langage GoIntroduction au langage Go
Introduction au langage Go
 
Spark Streaming
Spark StreamingSpark Streaming
Spark Streaming
 
Spring Batch ParisJUG
Spring Batch ParisJUG Spring Batch ParisJUG
Spring Batch ParisJUG
 
Apache Flink par Bilal Baltagi Paris Spark Meetup Dec 2015
Apache Flink par Bilal Baltagi Paris Spark Meetup Dec 2015Apache Flink par Bilal Baltagi Paris Spark Meetup Dec 2015
Apache Flink par Bilal Baltagi Paris Spark Meetup Dec 2015
 
Paris RailsCamp 2009
Paris RailsCamp 2009Paris RailsCamp 2009
Paris RailsCamp 2009
 
WS User Group - Spring Batch - Xebia
WS User Group - Spring Batch - XebiaWS User Group - Spring Batch - Xebia
WS User Group - Spring Batch - Xebia
 
Paris JUG Spring Batch
Paris JUG Spring BatchParis JUG Spring Batch
Paris JUG Spring Batch
 
Ajax - GTI780 & MTI780 - ETS - A08
Ajax - GTI780 & MTI780 - ETS - A08Ajax - GTI780 & MTI780 - ETS - A08
Ajax - GTI780 & MTI780 - ETS - A08
 
Chtijug springbatch 2011
Chtijug springbatch 2011Chtijug springbatch 2011
Chtijug springbatch 2011
 
Spring Batch Avance
Spring Batch AvanceSpring Batch Avance
Spring Batch Avance
 
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
 
Déploiement de Silverpeas sur JOnAS
Déploiement de Silverpeas sur JOnASDéploiement de Silverpeas sur JOnAS
Déploiement de Silverpeas sur JOnAS
 
Le futur d'apache cassandra
Le futur d'apache cassandraLe futur d'apache cassandra
Le futur d'apache cassandra
 
Spark dataframe
Spark dataframeSpark dataframe
Spark dataframe
 
Spark, ou comment traiter des données à la vitesse de l'éclair
Spark, ou comment traiter des données à la vitesse de l'éclairSpark, ou comment traiter des données à la vitesse de l'éclair
Spark, ou comment traiter des données à la vitesse de l'éclair
 

En vedette

Out ofmemoryerror what is the cost of java objects
Out ofmemoryerror  what is the cost of java objectsOut ofmemoryerror  what is the cost of java objects
Out ofmemoryerror what is the cost of java objectsJean-Philippe BEMPEL
 
Plugin logstash-filter-aggregate (meetup Elastic FR)
Plugin logstash-filter-aggregate (meetup Elastic FR)Plugin logstash-filter-aggregate (meetup Elastic FR)
Plugin logstash-filter-aggregate (meetup Elastic FR)Fabien Baligand
 
Solution de transfert mobile - Formats d'échange
Solution de transfert mobile - Formats d'échangeSolution de transfert mobile - Formats d'échange
Solution de transfert mobile - Formats d'échangeOCTO Technology
 
Formation GIT gratuite par ippon 2014
Formation GIT gratuite par ippon 2014Formation GIT gratuite par ippon 2014
Formation GIT gratuite par ippon 2014Ippon
 
JDBC / JPA / Hibernate: Sans maîtrise la puissance n’est rien!
JDBC / JPA / Hibernate: Sans maîtrise la puissance n’est rien!JDBC / JPA / Hibernate: Sans maîtrise la puissance n’est rien!
JDBC / JPA / Hibernate: Sans maîtrise la puissance n’est rien!bleporini
 
Performance ug#1
Performance ug#1Performance ug#1
Performance ug#1Marc Bojoly
 

En vedette (7)

Out ofmemoryerror what is the cost of java objects
Out ofmemoryerror  what is the cost of java objectsOut ofmemoryerror  what is the cost of java objects
Out ofmemoryerror what is the cost of java objects
 
Plugin logstash-filter-aggregate (meetup Elastic FR)
Plugin logstash-filter-aggregate (meetup Elastic FR)Plugin logstash-filter-aggregate (meetup Elastic FR)
Plugin logstash-filter-aggregate (meetup Elastic FR)
 
Solution de transfert mobile - Formats d'échange
Solution de transfert mobile - Formats d'échangeSolution de transfert mobile - Formats d'échange
Solution de transfert mobile - Formats d'échange
 
Formation GIT gratuite par ippon 2014
Formation GIT gratuite par ippon 2014Formation GIT gratuite par ippon 2014
Formation GIT gratuite par ippon 2014
 
Devoxx 15
Devoxx 15 Devoxx 15
Devoxx 15
 
JDBC / JPA / Hibernate: Sans maîtrise la puissance n’est rien!
JDBC / JPA / Hibernate: Sans maîtrise la puissance n’est rien!JDBC / JPA / Hibernate: Sans maîtrise la puissance n’est rien!
JDBC / JPA / Hibernate: Sans maîtrise la puissance n’est rien!
 
Performance ug#1
Performance ug#1Performance ug#1
Performance ug#1
 

Similaire à Perfug 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
 
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
 
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 JavaAntonio Gomes Rodrigues
 
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 2012slandelle
 
Backday xebia - Chercher la performance efficacement
Backday xebia - Chercher la performance efficacement Backday xebia - Chercher la performance efficacement
Backday xebia - Chercher la performance efficacement Publicis Sapient Engineering
 
Grails from scratch to prod - MixIT 2011
Grails from scratch to prod - MixIT 2011Grails from scratch to prod - MixIT 2011
Grails from scratch to prod - MixIT 2011Aurélien Maury
 
BreizhCamp 2019 - IoT et open source hardware pour la collecte de timeseries
BreizhCamp 2019 - IoT et open source hardware pour la collecte de timeseriesBreizhCamp 2019 - IoT et open source hardware pour la collecte de timeseries
BreizhCamp 2019 - IoT et open source hardware pour la collecte de timeseriesXavier MARIN
 
Game of upgrades to liferay dxp - ep1: Migration de données
Game of upgrades to liferay dxp - ep1: Migration de donnéesGame of upgrades to liferay dxp - ep1: Migration de données
Game of upgrades to liferay dxp - ep1: Migration de donnéesQuang Tu LE
 
Développer sereinement avec Node.js
Développer sereinement avec Node.jsDévelopper sereinement avec Node.js
Développer sereinement avec Node.jsJulien Giovaresco
 
Et pourquoi pas JEE ?
Et pourquoi pas JEE ?Et pourquoi pas JEE ?
Et pourquoi pas JEE ?PALO IT
 
Plongée au cœur du Framework .NET 4.5
Plongée au cœur du Framework .NET 4.5Plongée au cœur du Framework .NET 4.5
Plongée au cœur du Framework .NET 4.5Microsoft
 
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 Javascriptcodedarmor
 
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 mysqlCodizy
 
GPGPU facile avec JavaCL, et trivial avec ScalaCL !
GPGPU facile avec JavaCL, et trivial avec ScalaCL !GPGPU facile avec JavaCL, et trivial avec ScalaCL !
GPGPU facile avec JavaCL, et trivial avec ScalaCL !ochafik
 

Similaire à Perfug 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 !
 
Vert.x 3
Vert.x 3Vert.x 3
Vert.x 3
 
Introduction aux RIA (Rich Internet Applications)
Introduction aux RIA (Rich Internet Applications)Introduction aux RIA (Rich Internet Applications)
Introduction aux RIA (Rich Internet Applications)
 
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
 
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
 
Backday xebia - Chercher la performance efficacement
Backday xebia - Chercher la performance efficacement Backday xebia - Chercher la performance efficacement
Backday xebia - Chercher la performance efficacement
 
Journée DevOps : Tests de performance en continu
Journée DevOps : Tests de performance en continuJournée DevOps : Tests de performance en continu
Journée DevOps : Tests de performance en continu
 
Grails from scratch to prod - MixIT 2011
Grails from scratch to prod - MixIT 2011Grails from scratch to prod - MixIT 2011
Grails from scratch to prod - MixIT 2011
 
BreizhCamp 2019 - IoT et open source hardware pour la collecte de timeseries
BreizhCamp 2019 - IoT et open source hardware pour la collecte de timeseriesBreizhCamp 2019 - IoT et open source hardware pour la collecte de timeseries
BreizhCamp 2019 - IoT et open source hardware pour la collecte de timeseries
 
Game of upgrades to liferay dxp - ep1: Migration de données
Game of upgrades to liferay dxp - ep1: Migration de donnéesGame of upgrades to liferay dxp - ep1: Migration de données
Game of upgrades to liferay dxp - ep1: Migration de données
 
Développer sereinement avec Node.js
Développer sereinement avec Node.jsDévelopper sereinement avec Node.js
Développer sereinement avec Node.js
 
Et pourquoi pas JEE ?
Et pourquoi pas JEE ?Et pourquoi pas JEE ?
Et pourquoi pas JEE ?
 
Plongée au cœur du Framework .NET 4.5
Plongée au cœur du Framework .NET 4.5Plongée au cœur du Framework .NET 4.5
Plongée au cœur du Framework .NET 4.5
 
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
 
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
 
Service Workers
Service WorkersService Workers
Service Workers
 
GPGPU facile avec JavaCL, et trivial avec ScalaCL !
GPGPU facile avec JavaCL, et trivial avec ScalaCL !GPGPU facile avec JavaCL, et trivial avec ScalaCL !
GPGPU facile avec JavaCL, et trivial avec ScalaCL !
 
Javascript proprement
Javascript proprementJavascript proprement
Javascript proprement
 
Formation Google App Engine
Formation Google App EngineFormation Google App Engine
Formation Google App Engine
 

Perfug 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 @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 @blep
  • 3. About me • Brice LEPORINI • Développeur Java / Scala @blep http://the-babel-tower.github.io/ @blep
  • 5. Scott Oaks - Java Performance The definitive guide There is no magical -XX:+RunReallyFast option @blep
  • 6. Lenteurs avec 1 utilisateur? Ouvrir un shell sur la plateforme d’exécution @blep
  • 7. Collecter des données sur l'environnement concerné! @blep
  • 8. Lenteurs avec 1 utilisateur? Ouvrir un shell sur la plateforme d’exécution CPU bound? GC? @blep
  • 9. Les problèmes liés à la mémoire • Terminal avec jstat -gcutil @blep
  • 10. Young Generation Heap Eden From Space To Space Old Generation Survivor 1: new 2: minor 1 3: n minors 4: promotion @blep
  • 11. GC: la master class http://www.infoq.com/presentations/Understanding-Java-Garbage-Collection @blep
  • 12. Les GC Stop The World • Serial GC: 1 thread • Throughput Collector ou Parallel Collector: • multi threads young et old @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 @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 @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 @blep
  • 17. Maintenant qu'on en sait un peu plus sur les GC, lequel choisir? @blep
  • 19. Choix du GC • Batch: • Throughtput collector • Application transactionnelle: • GC concurrent • CMS heap < 4GB • G1 heap >= 4GB @blep
  • 20. Lenteurs avec 1 utilisateur? Ouvrir un shell sur la plateforme d’exécution CPU bound? GC? Prélever un heap dump @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 ... @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 @blep
  • 23. Memory Analyzer Tool (MAT) http://www.eclipse.org/mat/ 1 2 3 @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 @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 @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 @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) @blep
  • 28. Les états du thread @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 @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à @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) @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 @blep
  • 34. Ca dépend ! Dimensionner un pool de threads @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 @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) @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 @blep
  • 38. Identifier les consommateurs avec un profiler • Sampling ou profiling? @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 @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 @blep
  • 43. Optimisation IO • Utilisation de cache: • Applicatif • cache FS du kernel @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?) @blep
  • 45. 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 @blep
  • 46. Exemple du pool sous dimensionné @blep
  • 47. 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 @blep
  • 48. 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 @blep
  • 49. 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 @blep
  • 50. 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 @blep
  • 51. Optimisation IO • Utiliser les Buffered(In|Out)putStreams @blep
  • 52. 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 @blep
  • 53. Et la virtualisation? • Réservation de ressources! @blep https://www.youtube.com/watch?v=XK2sG7AiEY8
  • 54. 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 @blep