Heisenberg, Myoclonic Jerks of the Diaphragm and Java
Jun 15, 2016 | 6 MIN READ
Jun 15, 2016 | 6 MIN READ
I studied physics at university and one of the hardest, but most interesting, subjects was quantum mechanics. As part of this, we studied the famous Heisenberg’s Uncertainty Principal, which is also associated with the “Observer Effect”. Essentially, what this says is that the act of observing something (at the sub-atomic level) changes what you’re observing so that you can either know a particle’s position or momentum with accuracy, but not both at the same time. Right now I’m sure you’re wondering what this has to do with Java but bear with me.
Analysing performance in Java is not always straightforward because of the non-deterministic nature of the JVM. Memory management and specifically garbage collection is frequently cited as the cause for unresponsiveness in an application, and indeed, this is often the case. With the exception of C4 in Zing from Azul, all commercial garbage collectors (GCs) will use a full compacting stop-the-world collection of the old generation as a fallback to avoid throwing the undesirable OutOfMemoryError. The length of pause of application threads and, therefore, the application itself is proportional to the size of the heap: the bigger the heap, the longer the pause.
To analyse Java application performance requires special tools of which there are many to choose from, but this is where Heisenberg’s Uncertainty Principal becomes relevant to Java. To measure things (like GC pause times) involves the collection of data, which requires time and computing resources. Using processor cycles and writing to memory will reduce the resources available to application code, even if very slightly. The more fine-grained analysis you want to do, the more data needs to be collected and the bigger the impact you will have on the application’s performance. I’ve actually worked on some timing related bugs where adding debug code to collect data about the problem skewed things enough to make the problem disappear (which leaves you with a tricky decision: leave the debug code in and ignore the problem, or find some other way to fix it).
In the case of the garbage collector, most of the performance data is effectively available for free simply because the collector has to keep track of information as it does its own work. Unfortunately, it’s not true to state that because GC can cause significant pauses in Java applications, all significant pauses must be due to GC. There are other things within the JVM, like thread management and synchronisation, which can cause noticeable pauses in an application’s response. Similarly, there are effects from outside of the JVM at the operating system or hardware level that can cause an application to stall or become unresponsive because the JVM itself is no longer able to continue doing its work.
Which brings me to the third part of the title of this blog post: Myoclonic Jerks of the Diaphragm. According to Wikipedia, this is the technical term for a Hiccup, which is something that interrupts your ability to breathe. At Azul, we thought this was a good analogy for what happens to Java applications and so created jHiccup. Gil Tene, our CTO, wrote a blog post on How Java Got The Hiccups.
The concepts behind jHiccup are very simple:
Using jHiccup is extremely easy with three options for how to measure hiccups in your application:
java -Djava.library.path=/mylib -jar myApp.jarthen you just have to add jHiccup at the beginning, thus
jHiccup java -Djava.library.path=/mylib -jar myApp.jar
java –javaagent:jHiccup.jar -Djava.library.path=/mylib -jar myApp.jar
jHiccup -p(since this uses the same bash script referenced in the first form the platform you’re using will need to support a bash interpreter).
I will soon be writing a follow-up blog post that will talk more about how to interpret and make use of the results of jHiccup.
To download JHiccup, click here.