Self-Reflection of Java Performance Profile

Introspecting Instrumented Java using the Probes Open API

One of the more powerful aspects of the Probes Open API is the ability to introspect on the metering of instrumented methods executed by a thread. With this, a method can in effect ask itself “what is it that I do?” post the execution of some code block. This is achieved via metering ChangeSets.

Java already supports the ability to introspect on structure and to use such information to invoke behavior but it cannot self-reflect on such invocation.

Let’s take a small simple piece of code to demonstrate the runtime reflection capabilities offered by a metering engine with full Probes Open API support.

https://gist.github.com/autoletics/29d40a4ece5fc8fe01d7fa1b91f8faa9

Can the main() method be enhanced such that it can itself introspect on the call count and clock timing of methods executed with the scope of the loop?

SavePoints and ChangeSets

To reflect on the code execution occurring within the loop, including direct and nested method calls, grab the current thread Context, before entering the loop create a metering SavePoint, then following the termination of the loop generate a metering ChangeSet using the Context.compare() method.

https://gist.github.com/autoletics/a4f1bfe161d0cba869d52585d89bf009

The above can be shortened with an import static statement, as all the interfaces are enclosed within the Probes class — the only class in the API.

https://gist.github.com/autoletics/fe308cfd538f8a7708010c072d0d7cd7

With the ChangeSet, it is possible to introspect the call count for a method. Simply, look up the ChangePoint for a method. Check if is present in the set as it might not have been called or metered. Then retrieve the Change for the measure, clock.time, metered by the metering engine via the JVM agent.

https://gist.github.com/autoletics/0f9553ac2480eba478eebd5f778c85b3

The console output listing the metered call count for the ingress() method.

https://gist.github.com/autoletics/567d9a5639393e3668eb3bb48f0526f0

The ChangeSet can be used to iterate over all probes metered during the execution window demarcated by the savepoint() and compare() call sites.

https://gist.github.com/autoletics/47773bdda44a1b35eccabc63c12ab2ba

With Java 8 the above can be made significantly more concise and readable.

https://gist.github.com/autoletics/ec0822119a80d7c852c9d1fc22398070

Here is the console output with the Satoris instrumentation agent installed.

https://gist.github.com/autoletics/c55029f6bfa753c1e692c7a692e632b4

There’s no need to change the original sources to introduce such reflective reporting of metered performance within the execution scope of a thread. Instead use the interception mechanism supported in the Probes Open API.

https://gist.github.com/autoletics/a0362caeb51a38c0d9406799178800ad

The printed console out with an extra name included — the main() method.

https://gist.github.com/autoletics/d2f88931754dd29eb9ed8a70e5f563f4

Possibilities

The reflective capabilities of the Probes Open API are extremely powerful and have numerous potential use cases. It can be used to append metering profile information to outbound HTTP responses, to detect underlying behavioral changes across software releases or in the course of execution, to collect and store charge/show back data for each service request, as well as improve performance unit testing within a continuous integration pipeline.

http://www.autoletics.com/tools/satoris