BTrace and JStat - No Fluff Just Stuff

BTrace and JStat

Posted by: Ken Sipe on June 11, 2009

I just finished a JavaOne presentation on Debugging your Production JVM. The killer part and climax of the presentation was on BTrace. BTrace just rocks! As good as it is, the documentation and javadoc information is somewhat dated. This post will explain one of my favorite tool sets working together; that being jstat and Btrace.

JStat
Jstat is a tool that has been provided in the jdk bin directory since Java 5. It has a number features, which can be examined by using the flag -options:
jstat -options
The most significant in my opinion being jstat -gcutils which provides an output of jvm memory by compartment; survivor spaces, eden, old and perm space. Here are the steps if this is new to you:
1. start an demo application: java -jar Java2D.jar
2. get the pid: jps
3. lauch jstat: jstat -gcutil 1483
output:

S0 S1 E O P YGC YGCT FGC FGCT GCT
0.00 0.00 10.61 59.98 76.81 8 0.057 9 0.460 0.516
BTrace
Btrace is a tool that allows you to inject probes into a running java process to observe and debug an application. I won't go into "how" to use BTrace, as I've blogged on it in the past and the BTrace document does a good job of explaining it.

The area that is lacking is around the @Export annotation for BTrace scripts. There are no details in the documentation and the sample code comments says "// create a jvmstat counter using @Export"... yeah... right... Even the internal code comments and JavaDocs are just as vague. So if you are lost at this point, jstat use to be called jvmstat and was provided as part of the distribution of jvmstat. Even then there is no information on how to leverage the two... until now!!

Creating the Script
Take a look at the ThreadCounter.java file in the sample directory of BTrace. Any value you want to be exposed to jstat will need to be annotated with @Export. Then you will need to assign a value to this exported value with a static method from BtraceUtils. In the ThreadCounter example this is accomplished with perfLong("btrace.com.sun.btrace.samples.ThreadCounter.count"); The next step is to inject this code into a targeted JVM; such as:
btrace 1483 ../samples/ThreadCounter.java 

Accessing BTrace exports with jstat
The undocumented trick for jstat is that you have to specify -J-Djstat.showUnsupported=true and -name with the name of the exported variable defined by the perf statement. Here is the full command-line:
jstat -J-Djstat.showUnsupported=true -name btrace.com.sun.btrace.samples.ThreadCounter.count 1483




Thanks to Sundar at Sun for the enlightenment!
Ken Sipe

About Ken Sipe

Ken is a distributed application engineer. Ken has worked with Fortune 500 companies to small startups in the roles of developer, designer, application architect and enterprise architect. Ken's current focus is on containers, container orchestration, high scale micro-service design and continuous delivery systems.

Ken is an international speaker on the subject of software engineering speaking at conferences such as JavaOne, JavaZone, Great Indian Developer Summit (GIDS), and The Strange Loop. He is a regular speaker with NFJS where he is best known for his architecture and security hacking talks. In 2009, Ken was honored by being awarded the JavaOne Rockstar Award at JavaOne in SF, California and the JavaZone Rockstar Award at JavaZone in Oslo, Norway as the top ranked speaker.

Why Attend the NFJS Tour?

  • » Cutting-Edge Technologies
  • » Agile Practices
  • » Peer Exchange

Current Topics:

  • Languages on the JVM: Scala, Groovy, Clojure
  • Enterprise Java
  • Core Java, Java 8
  • Agility
  • Testing: Geb, Spock, Easyb
  • REST
  • NoSQL: MongoDB, Cassandra
  • Hadoop
  • Spring 4
  • Cloud
  • Automation Tools: Gradle, Git, Jenkins, Sonar
  • HTML5, CSS3, AngularJS, jQuery, Usability
  • Mobile Apps - iPhone and Android
  • More...
Learn More »