mjprof: monadic approach for jvm profiling

66
@lifeyx #Devoxx #Performance #AdoptOpenJDK mjprof : A Monadic Approach for JVM Profiling Haim Yadid Performize-IT

Upload: haim-yadid

Post on 08-Jul-2015

427 views

Category:

Software


0 download

DESCRIPTION

A traditional Java profiler consists of two components. One collects profile data from the running application and the other is a visualization user interface to query the data. The profiler capabilities are limited by the data collected but also by the provided reports and functionality. This can be limiting when it comes to complex query of data. In this session we will introduce mjprof. It is an open source textual visualization profiler. It is extremely powerful as it enables you to compose a sequence of simple steps (monads) such as filters, transformations, group-by which let you slice and dice the data to pinpoint the problem. Working with mjprof resembles working with UNIX pipes. We will explain how to use this tool and present use cases and success stories, using this profiler in the last months. mjprof is written in Java and can be found on github as part of the AdoptOpenJDK project.

TRANSCRIPT

Page 1: mjprof: Monadic approach for JVM profiling

@lifeyx#Devoxx #Performance #AdoptOpenJDK

mjprof : A Monadic Approach for JVM Profiling

Haim YadidPerformize-IT

Page 2: mjprof: Monadic approach for JVM profiling

@lifeyx#Devoxx #Performance #AdoptOpenJDK

About Me: Haim Yadid

• 21 Years of SW development experience

• independent Performance Expert

• Consulting R&D Groups

• Training: Java Performance Optimization

• Community leader : Java.IL

Page 3: mjprof: Monadic approach for JVM profiling

@lifeyx#Devoxx #Performance #AdoptOpenJDK

Java.IL

• Israeli Java Community and User Group

• Meetup : www.meetup.com/JavaIL/

• Twitter: @java_il

• ~ 400 members

• Meeting every month

Page 4: mjprof: Monadic approach for JVM profiling

@lifeyx#Devoxx #Performance #AdoptOpenJDK

Background &

Motivation

Page 5: mjprof: Monadic approach for JVM profiling

@lifeyx#Devoxx #Performance #AdoptOpenJDK

The Two Most Important Questions

Page 6: mjprof: Monadic approach for JVM profiling

@lifeyx#Devoxx #Performance #AdoptOpenJDK

The Two Most Important Questions

My wife asks me

Page 7: mjprof: Monadic approach for JVM profiling

@lifeyx#Devoxx #Performance #AdoptOpenJDK

The Two Most Important Questions

What are you doing? When will you be back?

My wife asks me

Page 8: mjprof: Monadic approach for JVM profiling

@lifeyx#Devoxx #Performance #AdoptOpenJDK

Profiler

• A Performance analysis tool

• Which answers questions about method calls:

• E.g. : Number of invocation, Average duration,CPU consumptions Contention Memory allocation IO, Cache misses etc…..

Page 9: mjprof: Monadic approach for JVM profiling

@lifeyx#Devoxx #Performance #AdoptOpenJDK

Statistical Profiler

• A.k.a. as Sampling Profiler

• Samples the treads activity every several milliseconds

• Not very accurate for short tasks

• Low/Medium overhead

• Do not provide the number of invocations

Page 10: mjprof: Monadic approach for JVM profiling

@lifeyx#Devoxx #Performance #AdoptOpenJDK

Instrumenting Profiler

• A.k.a Tracing

• Instruments the code

• Knows when a method starts and when it ends

• High overhead (depends on instrumentation)

Page 11: mjprof: Monadic approach for JVM profiling

@lifeyx#Devoxx #Performance #AdoptOpenJDK

Instrumenting Profiler

• A.k.a Tracing

• Instruments the code

• Knows when a method starts and when it ends

• High overhead (depends on instrumentation)

Public void foo(a) {Measure start timeincrease invocation count

bla bla;Measure end time

}

Injected code

Page 12: mjprof: Monadic approach for JVM profiling

@lifeyx#Devoxx #Performance #AdoptOpenJDK

jstack - A Poor Man’s Profiler

• The most trivial sampling profiler

• Part of the JDK

• Connects to a running JVM and samples all the threads

• Only once !

• Writes to standard output

Page 13: mjprof: Monadic approach for JVM profiling

@lifeyx#Devoxx #Performance #AdoptOpenJDK

And it looks like this

• For each thread we have the following block

Page 14: mjprof: Monadic approach for JVM profiling

@lifeyx#Devoxx #Performance #AdoptOpenJDK

And it looks like this

• For each thread we have the following block

"pool-35-thread-1" prio=5 tid=10315b800 nid=0x12c1fe000 waiting on condition [12c1fd000] java.lang.Thread.State: TIMED_WAITING (parking) at sun.misc.Unsafe.park(Native Method) - parking to wait for <107ac0140> (a java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject) at java.util.concurrent.locks.LockSupport.parkNanos(LockSupport.java:198) at java.util.concurrent.locks.AbstractQueuedSynchronizer$ConditionObject.awaitNanos ..... Locked ownable synchronizers: - None

Thread name Priority Id and native id

Page 15: mjprof: Monadic approach for JVM profiling

@lifeyx#Devoxx #Performance #AdoptOpenJDK

Now do this a Million Times!

Page 16: mjprof: Monadic approach for JVM profiling

@lifeyx#Devoxx #Performance #AdoptOpenJDK

Now do this a Million Times!

• Tons of threads

• Deep stacks

Page 17: mjprof: Monadic approach for JVM profiling

@lifeyx#Devoxx #Performance #AdoptOpenJDK

mjprof

Page 18: mjprof: Monadic approach for JVM profiling

@lifeyx#Devoxx #Performance #AdoptOpenJDK

mjprof

• A command line tool

• Acts on jstack output

• Extends it (enriched thread dumps)

• Applies a sequence of operations (monads) to

• Filter

• Aggregate

• Manipulate

Page 19: mjprof: Monadic approach for JVM profiling

@lifeyx#Devoxx #Performance #AdoptOpenJDK

Prerequisites

• Java installed

• Set JAVA_HOME (JDK1.7 or later)

• Add ${JAVA_HOME}/bin to path

• Attaching to processes requires JDK and not JRE

• Can run on a headless machine

Page 20: mjprof: Monadic approach for JVM profiling

@lifeyx#Devoxx #Performance #AdoptOpenJDK

Installing mjprof

• Git repo : https://github.com/AdoptOpenJDK/mjprof

• Download and unzip unzip mjprof1.0-bin.zip

• Or clone and build mvn install assembly:assembly

• Add mjprof directory to your path

Page 21: mjprof: Monadic approach for JVM profiling

@lifeyx#Devoxx #Performance #AdoptOpenJDK

Synopsis and Help (Smoke test)

• Running mjprof without parameters will print help

• It is a good way to see it is functioning

Page 22: mjprof: Monadic approach for JVM profiling

@lifeyx#Devoxx #Performance #AdoptOpenJDK

Synopsis and Help (Smoke test)

• Running mjprof without parameters will print help

• It is a good way to see it is functioning

➜ mjprof git:(master) ✗ mjprof Synopsis A list of the following monads concatenated with . … Data sources: jstack/pid,[count],[sleep]/ -Generate dumps using stack path/path/ -Read thread dump from file stdin -Read thread dumps from standard input visualvm/path/ -Read profiling session from xml export of VisualVM

….

Page 23: mjprof: Monadic approach for JVM profiling

@lifeyx#Devoxx #Performance #AdoptOpenJDK

Monads

• Pipeline Building blocks

• Monads can

• Collect data

• Filter out certain threads

• Transform threads information

• Aggregate threads information

• Snapshot write state to a file or GUI

• Concatenate with a . (period)

Page 24: mjprof: Monadic approach for JVM profiling

@lifeyx#Devoxx #Performance #AdoptOpenJDK

Data Sourcesstdin

file

jstack

jmx

Page 25: mjprof: Monadic approach for JVM profiling

@lifeyx#Devoxx #Performance #AdoptOpenJDK

Data Sources

• cat mythreaddump.txt | mjprof…stdin

file

jstack

jmx

Page 26: mjprof: Monadic approach for JVM profiling

@lifeyx#Devoxx #Performance #AdoptOpenJDK

Data Sources

• cat mythreaddump.txt | mjprof…

• mjprof path/mythreaddump.txt/

stdin

file

jstack

jmx

Page 27: mjprof: Monadic approach for JVM profiling

@lifeyx#Devoxx #Performance #AdoptOpenJDK

Data Sources

• cat mythreaddump.txt | mjprof…

• mjprof path/mythreaddump.txt/

• mjprof jstack/19873/

stdin

file

jstack

jmx

Page 28: mjprof: Monadic approach for JVM profiling

@lifeyx#Devoxx #Performance #AdoptOpenJDK

Data Sources

• cat mythreaddump.txt | mjprof…

• mjprof path/mythreaddump.txt/

• mjprof jstack/19873/

• mjprof jmx/myhost:65327/

stdin

file

jstack

jmx

Page 29: mjprof: Monadic approach for JVM profiling

@lifeyx#Devoxx #Performance #AdoptOpenJDK

Monads

contains -contains group

merge

sort

-sort

frame

count

mergedcalles

-frame

top

bottom

trimbelow

namesuf

-fn

-pkg

-fn-prop

jvm -jvm

blocked

locks

-lockswaiting

running withstack

Filters Aggregations Stack frame level

stdout

gui

snapshot

output

Page 30: mjprof: Monadic approach for JVM profiling

@lifeyx#Devoxx #Performance #AdoptOpenJDK

Extending mjprof

• mjprof is inherently extensible

• Macros

• A text file named macros.properties

• Contains a sequence of macros

• Plugins

• Annotate your extension with @Plugin

• Compile it and place your jar in the directory plugins under mjprof installation

Page 31: mjprof: Monadic approach for JVM profiling

@lifeyx#Devoxx #Performance #AdoptOpenJDK

10 mjprof Recipes

Page 32: mjprof: Monadic approach for JVM profiling

@lifeyx#Devoxx #Performance #AdoptOpenJDK

Page 33: mjprof: Monadic approach for JVM profiling

@lifeyx#Devoxx #Performance #AdoptOpenJDK

Question: How many threads my process has?

Page 34: mjprof: Monadic approach for JVM profiling

@lifeyx#Devoxx #Performance #AdoptOpenJDK

Question: How many threads my process has?

mjprof jstack/1971/path/stack.txt/

jstack/MainClass/

Page 35: mjprof: Monadic approach for JVM profiling

@lifeyx#Devoxx #Performance #AdoptOpenJDK

Question: How many threads my process has?

➜ distro mjprof jstack/1971/.count 2014-11-01 10:34:10Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.0-b70 mixed mode):

Total number of threads is 1045

mjprof jstack/1971/ . countpath/stack.txt/

jstack/MainClass/

Page 36: mjprof: Monadic approach for JVM profiling

@lifeyx#Devoxx #Performance #AdoptOpenJDK

Question: How many jetty thread are working ATM?

Page 37: mjprof: Monadic approach for JVM profiling

@lifeyx#Devoxx #Performance #AdoptOpenJDK

Question: How many jetty thread are working ATM?

mjprof jstack/MyApp/

Page 38: mjprof: Monadic approach for JVM profiling

@lifeyx#Devoxx #Performance #AdoptOpenJDK

Question: How many jetty thread are working ATM?

mjprof jstack/MyApp/ . contains/name,qtp/

Page 39: mjprof: Monadic approach for JVM profiling

@lifeyx#Devoxx #Performance #AdoptOpenJDK

Question: How many jetty thread are working ATM?

➜ 04112014 mjprof jstack/My4tApp/.contains/name,qtp/ 2014-11-04 20:05:03Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.0-b70 mixed mode):

"qtp817406040-17-selector-ServerConnectorManager@69b87e8d/3" prio=5 ….3 runnable [0x000000011bc5f000] java.lang.Thread.State: RUNNABLE at sun.nio.ch.KQueueArrayWrapper.kevent0(Native Method) at sun.nio.ch.KQueueArrayWrapper.poll(KQueueArrayWrapper.java:202) at sun.nio.ch.KQueueSelectorImpl.doSelect(KQueueSelectorImpl.java:103) at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:86) - locked <0x0000000780209080> (a sun.nio.ch.Util$2) - locked <0x0000000780209070> (a java.util.Collections$UnmodifiableSet)

mjprof jstack/MyApp/ . contains/name,qtp/contains/state,RUN/.

Page 40: mjprof: Monadic approach for JVM profiling

@lifeyx#Devoxx #Performance #AdoptOpenJDK

Question: How many jetty thread are working ATM?

➜ 04112014 mjprof jstack/My4tApp/.contains/name,qtp/ 2014-11-04 20:05:03Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.0-b70 mixed mode):

"qtp817406040-17-selector-ServerConnectorManager@69b87e8d/3" prio=5 ….3 runnable [0x000000011bc5f000] java.lang.Thread.State: RUNNABLE at sun.nio.ch.KQueueArrayWrapper.kevent0(Native Method) at sun.nio.ch.KQueueArrayWrapper.poll(KQueueArrayWrapper.java:202) at sun.nio.ch.KQueueSelectorImpl.doSelect(KQueueSelectorImpl.java:103) at sun.nio.ch.SelectorImpl.lockAndDoSelect(SelectorImpl.java:86) - locked <0x0000000780209080> (a sun.nio.ch.Util$2) - locked <0x0000000780209070> (a java.util.Collections$UnmodifiableSet)

mjprof jstack/MyApp/ . contains/name,qtp/count.contains/state,RUN/.

Page 41: mjprof: Monadic approach for JVM profiling

@lifeyx#Devoxx #Performance #AdoptOpenJDK

Question: Which threads are running my logic ?

Page 42: mjprof: Monadic approach for JVM profiling

@lifeyx#Devoxx #Performance #AdoptOpenJDK

Question: Which threads are running my logic ?

2014-11-04 20:11:55Full thread dump Java HotSpot(TM) 64-Bit Server VM (25.0-b70 mixed mode):

"Indexing daemon" prio=5 tid=0x00007fb306bf4800 nid=0x6307 waiting on condition [0x000000011c171000] java.lang.Thread.State: TIMED_WAITING (sleeping) at java.lang.Thread.sleep(Native Method) at com.myapp.IndexManagement$1.run(IndexManagement.java:148)

"main" prio=5 tid=0x00007fb303809000 nid=0x1303 in Object.wait() [0x0000000105500000] java.lang.Thread.State: WAITING (on object monitor) at java.lang.Object.wait(Native Method) at java.lang.Object.wait(Object.java:502) at com.myapp.MyAppApp.main(MyAppApp.java:18)

mjprof jstack/MyApp/ . contains/stack,myapp/

Page 43: mjprof: Monadic approach for JVM profiling

@lifeyx#Devoxx #Performance #AdoptOpenJDK

Question: Stack-trace is cluttered, how do I shorten it ?

Page 44: mjprof: Monadic approach for JVM profiling

@lifeyx#Devoxx #Performance #AdoptOpenJDK

Question: Stack-trace is cluttered, how do I shorten it ?

mjprof jmx/MyApp/ .

Page 45: mjprof: Monadic approach for JVM profiling

@lifeyx#Devoxx #Performance #AdoptOpenJDK

Question: Stack-trace is cluttered, how do I shorten it ?

mjprof jmx/MyApp/ . frame/mycompany/

Page 46: mjprof: Monadic approach for JVM profiling

@lifeyx#Devoxx #Performance #AdoptOpenJDK

Question: Stack-trace is cluttered, how do I shorten it ?

mjprof jmx/MyApp/ . frame/mycompany/-frame/grizzly/

Page 47: mjprof: Monadic approach for JVM profiling

@lifeyx#Devoxx #Performance #AdoptOpenJDK

Question: Stack-trace is cluttered, how do I shorten it ?

mjprof jmx/MyApp/ . frame/mycompany/-frame/grizzly/top/3/

Page 48: mjprof: Monadic approach for JVM profiling

@lifeyx#Devoxx #Performance #AdoptOpenJDK

Question: How can I group threads by state ?

Page 49: mjprof: Monadic approach for JVM profiling

@lifeyx#Devoxx #Performance #AdoptOpenJDK

mjprof jmx/MyApp/ . group/state/ gui.

Question: How can I group threads by state ?

Page 50: mjprof: Monadic approach for JVM profiling

@lifeyx#Devoxx #Performance #AdoptOpenJDK

Question: How do I aggregate several thread dumps

Page 51: mjprof: Monadic approach for JVM profiling

@lifeyx#Devoxx #Performance #AdoptOpenJDK

Question: How do I aggregate several thread dumps

mjprof jmx/MyApp,10,1000/

Page 52: mjprof: Monadic approach for JVM profiling

@lifeyx#Devoxx #Performance #AdoptOpenJDK

Question: How do I aggregate several thread dumps

mjprof jmx/MyApp,10,1000/ .group/state/

merge

Page 53: mjprof: Monadic approach for JVM profiling

@lifeyx#Devoxx #Performance #AdoptOpenJDK

Question: How do I aggregate several thread dumps

mjprof jmx/MyApp,10,1000/ .group/state/

merge .

Page 54: mjprof: Monadic approach for JVM profiling

@lifeyx#Devoxx #Performance #AdoptOpenJDK

Question: How can I combine thread dumps from several processes?

Page 55: mjprof: Monadic approach for JVM profiling

@lifeyx#Devoxx #Performance #AdoptOpenJDK

Question: How can I combine thread dumps from several processes?

mjprof jmx/myhost1.com:5467/ .

group/state/ gui.jmx/myhost2.com:5467/ .

Page 56: mjprof: Monadic approach for JVM profiling

@lifeyx#Devoxx #Performance #AdoptOpenJDK

Page 57: mjprof: Monadic approach for JVM profiling

@lifeyx#Devoxx #Performance #AdoptOpenJDK

How do I measure thread pool CPU consumption?

Page 58: mjprof: Monadic approach for JVM profiling

@lifeyx#Devoxx #Performance #AdoptOpenJDK

How do I measure thread pool CPU consumption?

mjprof jmxc/MyApp/

Page 59: mjprof: Monadic approach for JVM profiling

@lifeyx#Devoxx #Performance #AdoptOpenJDK

How do I measure thread pool CPU consumption?

mjprof jmxc/MyApp/ . contains/name,COFFEE/

Page 60: mjprof: Monadic approach for JVM profiling

@lifeyx#Devoxx #Performance #AdoptOpenJDK

"*" count=7 tid=* cpu_ns=1164536000 wall_ms=4804 %cpu=24.24 java.lang.Thread.State: TIMED_WAITING100.00% [7/7]\ at Thread.run(Thread.java:744)100.00% [7/7] \ at Sleeper.run(Sleeper.java:51)100.00% [7/7] \ at Sleeper.loopForever(Sleeper.java:37)100.00% [7/7] \ at Sleeper.longerStackTrace(Sleeper.java:32)100.00% [7/7] \ at Sleeper.longerStackTrace(Sleeper.java:32)100.00% [7/7] \ at Sleeper.longerStackTrace(Sleeper.java:32)100.00% [7/7] \ at Sleeper.longerStackTrace(Sleeper.java:32)100.00% [7/7] \ at Sleeper.longerStackTrace(Sleeper.java:32)100.00% [7/7] \ at Sleeper.longerStackTrace(Sleeper.java:30)100.00% [7/7] \ at Recurse.singleCycle(Recurse.java:16)100.00% [7/7] \ at Recurse.doRecursion(Recurse.java:25)100.00% [7/7] \ at Recurse.doRecursion(Recurse.java:25)

How do I measure thread pool CPU consumption?

mjprof jmxc/MyApp/ . contains/name,COFFEE/-pkg group..

Page 61: mjprof: Monadic approach for JVM profiling

@lifeyx#Devoxx #Performance #AdoptOpenJDK

Question: Which threads are blocked by the lock I hold

Page 62: mjprof: Monadic approach for JVM profiling

@lifeyx#Devoxx #Performance #AdoptOpenJDK

Question: Which threads are blocked by the lock I hold

mjprof path/threaddump.txt/ .blockedcontains/stack,0x00000007aab51b38/

.

Page 63: mjprof: Monadic approach for JVM profiling

@lifeyx#Devoxx #Performance #AdoptOpenJDK

Question: What is the overall locking state of my application

Page 64: mjprof: Monadic approach for JVM profiling

@lifeyx#Devoxx #Performance #AdoptOpenJDK

Question: What is the overall locking state of my application

mjprof path/threaddump.txt/ .contains/stack,myapp/locks

.

"CPU3_5" prio=5 tid=0x00007fc4f4889800 nid=0x5703 waiting for monitor… java.lang.Thread.State: BLOCKED (on object monitor) - waiting to lock <0x00000007aad98988> (a java.lang.Object)

"CPU3_4" prio=5 tid=0x00007fc4f404a800 nid=0x5503 waiting for monitor… java.lang.Thread.State: BLOCKED (on object monitor) - waiting to lock <0x00000007aad98988> (a java.lang.Object)

"CPU3_3" prio=5 tid=0x00007fc4f4049800 nid=0x5303 waiting on … java.lang.Thread.State: TIMED_WAITING (sleeping) - locked <0x00000007aad98988> (a java.lang.Object)

Page 65: mjprof: Monadic approach for JVM profiling

@lifeyx#Devoxx #Performance #AdoptOpenJDK

Page 66: mjprof: Monadic approach for JVM profiling

@lifeyx#Devoxx #Performance #AdoptOpenJDK

Thanks / Contact Me

http://il.linkedin.com/in/haimyadid

[email protected]

www.performize-it.com

blog.performize-it.com

https://github.com/lifey

@lifeyx