Skip to content

Collection of small Java serviceability improvements based on JVM Tool Interface

License

Notifications You must be signed in to change notification settings

tsarenkotxt/jvmti-tools

 
 

Repository files navigation

JVM TI tools

This fork contains compiled(jdk11) libs for darwin(macOS):

compiled-libs/antimodule.dylib
compiled-libs/heapsampler.dylib
compiled-libs/richNPE.dylib
compiled-libs/vmtrace.dylib

Collection of small Java serviceability improvements based on JVM Tool Interface.

richNPE

Enhances NullPointerException thrown by JVM with a detailed error message.

For example, there are several reasons why the following code may throw NullPointerException:

long value = source.map().get(key);

Either

  • source is null, or
  • map() returns null, or
  • get() returns null and the subsequent unboxing fails.

The standard JDK exception message does not give a clue which expression exactly caused NPE, but when using this tool, the message will look like

java.lang.NullPointerException: Called method 'get()' on null object at bci 19

While JDK-8218628 is going to be implemented in JDK 13, the given agent improves NPE messages for existing JDK 8-12.

Compilation

# Linux
g++ -O2 -fPIC -shared -I $JAVA_HOME/include -I $JAVA_HOME/include/linux -olibrichNPE.so richNPE.cpp

# Windows
cl /O2 /LD /I "%JAVA_HOME%/include" -I "%JAVA_HOME%/include/win32" richNPE.cpp

Usage

java -agentpath:/path/to/librichNPE.so MainClass

vmtrace

Traces basic JVM events like

  • Thread started / terminated
  • GC started / finished
  • Class loading / class prepared
  • Method compiled / unloaded
  • Dynamic code generated

Example output

[0.05588] Method compiled: java/lang/String.<init> (1056 bytes)
[0.05597] Loading class: java/io/FileOutputStream$1 (557 bytes)
[0.05600] Class prepared: java/io/FileOutputStream$1
[0.05602] Method compiled: java/lang/String.hashCode (512 bytes)
[0.05618] Thread started: main
[0.05622] Loading class: sun/launcher/LauncherHelper (14692 bytes)
[0.05640] Dynamic code generated: I2C/C2I adapters(0xabbebebea0000000)@0x00000000032c38a0 (392 bytes)
[0.05642] Dynamic code generated: I2C/C2I adapters(0xbebebea0)@0x00000000032c36a0 (376 bytes)
...

Compilation

# Linux
g++ -O2 -fPIC -shared -I $JAVA_HOME/include -I $JAVA_HOME/include/linux -olibvmtrace.so vmtrace.cpp

# Windows
cl /O2 /LD /I "%JAVA_HOME%/include" -I "%JAVA_HOME%/include/win32" vmtrace.cpp

Usage

java -agentpath:/path/to/libvmtrace.so[=output.log] MainClass

The log will be written to the file specified in the agent arguments, or to stderr if no arguments given.

antimodule

Removes Jigsaw restrictions in JDK 9+ by opening and exporting all JDK modules to the unnamed module.

This allows Reflection access to all JDK private fields and methods with no warnings, even when --illegal-access=deny option specified. This also makes all JDK internal classes like sun.nio.ch.DirectBuffer accessible by the unnamed module.

The agent is helpful for running older Java applications on JDK 9+ when application uses private APIs.

Compilation

# Linux
g++ -O2 -fPIC -shared -I $JAVA_HOME/include -I $JAVA_HOME/include/linux -olibantimodule.so antimodule.cpp

# Windows
cl /O2 /LD /I "%JAVA_HOME%/include" -I "%JAVA_HOME%/include/win32" antimodule.cpp

Usage

java -agentpath:/path/to/libantimodule.so MainClass

heapsampler

The example of low-overhead heap allocation profiler based on JEP 331.

Requires JDK 11 or later.

Example output

The output is generated in collapsed stacktraces format suitable for generating Flame Graphs.

Allocate.main;java.lang.Long.valueOf;java.lang.Long 49
Allocate.main;java.lang.Object[] 31
java.lang.Thread.run;jdk.internal.misc.Signal$1.run;java.lang.Terminator$1.handle;java.lang.Class 1
jdk.internal.misc.Signal.dispatch;java.lang.Class 1

See async-profiler for more information about allocation profiling and Flame Graphs. Note that heapsampler works only on JDK 11+, while async-profiler is capable of generating allocation profiles on JDK 7+.

Compilation

# Linux
g++ -O2 -fPIC -shared -I $JAVA_HOME/include -I $JAVA_HOME/include/linux -olibheapsampler.so heapsampler.cpp

# Windows
cl /O2 /LD /I "%JAVA_HOME%/include" -I "%JAVA_HOME%/include/win32" heapsampler.cpp

Usage

java -agentpath:/path/to/libheapsampler.so[=interval] MainClass > output.txt

The agent can be also loaded dynamically in run-time:

jcmd <pid> JVMTI.agent_load /path/to/libheapsampler.so [interval]

The optional interval argument specifies the sampling interval in bytes. The default value is 512 KB. The output is printed on stdout.

About

Collection of small Java serviceability improvements based on JVM Tool Interface

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages

  • C++ 93.3%
  • Shell 3.9%
  • Java 2.8%