Many Application Performance Management (APM) vendors that give insight into the runtime behavior of JVMs use interfaces provided by the Java Runtime. Traditionally Java offered the JVMPI Interface which was replaced by JVMTI with Java 5. Both options allow a tool vendor to load a native library (often called native agent) into the same process as the JVM. This library gets access to JVM state and certain aspects of application execution through a native API. As the library is not running as part of the JVM it is not impacted by JVM stops (e.g: longer Garbage Collection suspensions, runtime errors …) and can therefore continue to deliver data to the external tool.
As an alternative to these native interfaces Java 5 also introduced a pure Java interface. This option loads the agent INTO the JVM and runs as part of the JVM. The “downside” is that this agent gets loaded at a later stage of the JVM Startup Sequence. It is also impacted by JVM stops or Java runtime problems and won’t be able to report certain type of error information.
In this blog we will highlight some of the reasons why our engineering team decided on the native approach in combination with bytecode instrumentation (BCI) vs. moving to the Java based approach: