No soy ningún hacker de perf, de JVM, ni de sistemas.
“We should forget about small efficiencies, say about 97% of the time: premature optimization is the root of all evil”
Donald Kunth
“Flame graphs are a visualization of profiled software, allowing the most frequent code-paths to be identified quickly and accurately”
"main" #1 prio=5 os_prio=31 tid=0x00007f904c00c000 nid=0x1703 runnable [0x0000700000219000]
java.lang.Thread.State: RUNNABLE
at com.jerolba.codemotion.ElQuijote.toLowerCase(ElQuijote.java:98)
at com.jerolba.codemotion.ElQuijote.lambda$toLowerCase$3(ElQuijote.java:71)
at com.jerolba.codemotion.ElQuijote$$Lambda$6/2030562336.apply(Unknown Source)
at java.util.stream.ReferencePipeline$3$1.accept(ReferencePipeline.java:193)
at java.util.ArrayList$ArrayListSpliterator.forEachRemaining(ArrayList.java:1374)
at java.util.stream.AbstractPipeline.copyInto(AbstractPipeline.java:481)
at java.util.stream.AbstractPipeline.wrapAndCopyInto(AbstractPipeline.java:471)
at java.util.stream.ReduceOps$ReduceOp.evaluateSequential(ReduceOps.java:708)
at java.util.stream.AbstractPipeline.evaluate(AbstractPipeline.java:234)
at java.util.stream.ReferencePipeline.collect(ReferencePipeline.java:499)
at com.jerolba.codemotion.ElQuijote.toLowerCase(ElQuijote.java:71)
at com.jerolba.codemotion.ElQuijote.readBook(ElQuijote.java:43)
at com.jerolba.codemotion.ElQuijote.main(ElQuijote.java:30)
java 339/363 [002] 7628263.042557: cycles:
ffffffff8104f45a native_write_msr_safe ([kernel.kallsyms])
ffffffff8102f8bc intel_pmu_enable_all ([kernel.kallsyms])
ffffffff81029b14 x86_pmu_enable ([kernel.kallsyms])
ffffffff81142a77 perf_pmu_enable ([kernel.kallsyms])
ffffffff81027bfa x86_pmu_commit_txn ([kernel.kallsyms])
ffffffff811434f0 group_sched_in ([kernel.kallsyms])
ffffffff811439b2 __perf_event_enable ([kernel.kallsyms])
ffffffff8113f620 remote_function ([kernel.kallsyms])
ffffffff810dc880 generic_smp_call_function_single_interrupt ([kernel.kallsyms])
ffffffff81040ac7 smp_call_function_single_interrupt ([kernel.kallsyms])
ffffffff81732a5d call_function_single_interrupt ([kernel.kallsyms])
ffffffff8160b55e sock_aio_write ([kernel.kallsyms])
ffffffff811bd4aa do_sync_write ([kernel.kallsyms])
ffffffff811bdd2d vfs_write ([kernel.kallsyms])
ffffffff811be669 sys_write ([kernel.kallsyms])
ffffffff8173186d system_call_fastpath ([kernel.kallsyms])
7f35c130035d [unknown] (/lib/x86_64-linux-gnu/libpthread-2.19.so)
7f35a979cb8b Lsun/nio/ch/FileDispatcherImpl;.write0 (/tmp/perf-339.map)
7f35a987dadc Lsun/nio/ch/SocketChannelImpl;.write (/tmp/perf-339.map)
7f35a9878a50 Lio/netty/channel/nio/AbstractNioByteChannel;.doWrite (/tmp/perf-339.map)
7f35a986f204 Lio/netty/channel/DefaultChannelPipeline$HeadContext;.flush (/tmp/perf-339.map)
7f35a97ba324 Lio/netty/channel/AbstractChannelHandlerContext;.flush (/tmp/perf-339.map)
7f35a98644e4 Lio/netty/channel/ChannelOutboundHandlerAdapter;.flush (/tmp/perf-339.map)
7f35a97ba324 Lio/netty/channel/AbstractChannelHandlerContext;.flush (/tmp/perf-339.map)
7f35a9863624 Lio/netty/channel/ChannelDuplexHandler;.flush (/tmp/perf-339.map)
7f35a97ba324 Lio/netty/channel/AbstractChannelHandlerContext;.flush (/tmp/perf-339.map)
7f35a935c438 Lorg/vertx/java/core/net/impl/VertxHandler;.channelReadComplete (/tmp/perf-339.map)
7f35a92e11d4 Lio/netty/channel/AbstractChannelHandlerContext;.fireChannelReadComplete (/tmp/perf-339.map)
7f35a935cc98 Lio/netty/handler/codec/ByteToMessageDecoder;.channelReadComplete (/tmp/perf-339.map)
7f35a92e11d4 Lio/netty/channel/AbstractChannelHandlerContext;.fireChannelReadComplete (/tmp/perf-339.map)
7f35a955a3e8 Lio/netty/channel/nio/AbstractNioByteChannel$NioByteUnsafe;.read (/tmp/perf-339.map)
7f35a973a20c Lio/netty/channel/nio/NioEventLoop;.processSelectedKeysOptimized (/tmp/perf-339.map)
7f35a91530b0 Lio/netty/channel/nio/NioEventLoop;.processSelectedKeys (/tmp/perf-339.map)
7f35a9007c4d Interpreter (/tmp/perf-339.map)
7f35a9007c4d Interpreter (/tmp/perf-339.map)
7f35a9007c92 Interpreter (/tmp/perf-339.map)
7f35a90007a7 call_stub (/tmp/perf-339.map)
7f35c01c2776 JavaCalls::call_helper(JavaValue*, methodHandle*, JavaCallArguments*, Thread*) (/usr/lib/jvm/jdk1.8.0_60/jre/lib/amd64/server/libjvm.so)
7f35c01c2c81 JavaCalls::call_virtual(JavaValue*, KlassHandle, Symbol*, Symbol*, JavaCallArguments*, Thread*) (/usr/lib/jvm/jdk1.8.0_60/jre/lib/amd64/server/libjvm.so)
7f35c01c3127 JavaCalls::call_virtual(JavaValue*, Handle, KlassHandle, Symbol*, Symbol*, Thread*) (/usr/lib/jvm/jdk1.8.0_60/jre/lib/amd64/server/libjvm.so)
7f35c0259e60 thread_entry(JavaThread*, Thread*) (/usr/lib/jvm/jdk1.8.0_60/jre/lib/amd64/server/libjvm.so)
7f35c059f9cf JavaThread::thread_main_inner() (/usr/lib/jvm/jdk1.8.0_60/jre/lib/amd64/server/libjvm.so)
7f35c059fafc JavaThread::run() (/usr/lib/jvm/jdk1.8.0_60/jre/lib/amd64/server/libjvm.so)
7f35c0453718 java_start(Thread*) (/usr/lib/jvm/jdk1.8.0_60/jre/lib/amd64/server/libjvm.so)
7f35c12f9182 start_thread (/lib/x86_64-linux-gnu/libpthread-2.19.so)
Métodos separados por ;
main;foo 1
main;foo;car 3
main;foo;abc 10
main;foo;abc;pof 4
main;bar;car 3
main;bar;abc 7
main;zas 15
cat stacks.txt | flamegraph.pl > flamegraph.svg
Los giramos ↺
4
3 10 pof 3 7
1 car abc abc car abc 15
foo foo foo foo bar bar zas
main main main main main main main
Lo ordenamos alfabéticamente
4
7 3 10 pof 3
abc car 1 abc abc car 15
bar bar foo foo foo foo zas
main main main main main main main
¡El mecanismo que use para hacer el sampleo!
API oficial de la JVM y válido para cualquier implementación "certificada".
API interna de la JVM de Oracle
¿Qué pasa con todo el código que no es java?
git clone git@github.com:brendangregg/FlameGraph.git
export FLAMEGRAPH_DIR=/path/donde/clonaste/FlameGraph
Ejecuta tu código con monitorización
java -XX:+UnlockCommercialFeatures -XX:+FlightRecorder
-XX:+UnlockDiagnosticVMOptions -XX:+DebugNonSafepoints
-XX:StartFlightRecording=delay=1s,duration=90s,filename=result.jfr,settings=profile
-jar yourApp.jar your_app_params
https://github.com/chrishantha/jfr-flame-graph
¿Preparado?
¿Seguro?
¡¿Seguro?!
¡¿SEGURO?!
java 22176 3385.271871: 22719600 cycles:
a912a3 CollectedHeap::post_allocation_setup_array (/usr/lib/jvm/java-8-oracle/jre/lib/amd64/server/libjvm.so)
a90bc9 TypeArrayKlass::allocate_common (/usr/lib/jvm/java-8-oracle/jre/lib/amd64/server/libjvm.so)
6e4382 jni_NewByteArray (/usr/lib/jvm/java-8-oracle/jre/lib/amd64/server/libjvm.so)
1c0e8 JNU_NewStringPlatform (/usr/lib/jvm/java-8-oracle/jre/lib/amd64/libjava.so)
15d42 Java_java_io_UnixFileSystem_list (/usr/lib/jvm/java-8-oracle/jre/lib/amd64/libjava.so)
7f0c891c54fc [unknown] (/tmp/perf-22170.map)
7f0c891d3364 [unknown] (/tmp/perf-22170.map)
7f0c891ea894 [unknown] (/tmp/perf-22170.map)
7f0c890082bd [unknown] (/tmp/perf-22170.map)
7f0c890007a7 [unknown] (/tmp/perf-22170.map)
693e76 JavaCalls::call_helper (/usr/lib/jvm/java-8-oracle/jre/lib/amd64/server/libjvm.so)
6d5292 jni_invoke_static (/usr/lib/jvm/java-8-oracle/jre/lib/amd64/server/libjvm.so)
6f1afa jni_CallStaticVoidMethod (/usr/lib/jvm/java-8-oracle/jre/lib/amd64/server/libjvm.so)
80ff JavaMain (/usr/lib/jvm/java-8-oracle/jre/lib/amd64/jli/libjli.so)
76da start_thread (/lib/x86_64-linux-gnu/libpthread-2.24.so)
https://github.com/jvm-profiling-tools/perf-map-agent
sudo perf record -F 99 -a -g -p $pid -- sleep 90
perf script | $FLAMEGRAPH_DIR/stackcollapse-perf.pl | $FLAMEGRAPH_DIR/flamegraph.pl --color=java --hash
> flamegraph.svg