Fundamentals 9 min read

Analyzing a JVM Crash Caused by Compressed Oops and MemberName vmtarget Mis‑handling

This article walks through a JVM crash that occurs during garbage collection, explains how to use the SA tool CLHSDB to locate the offending object, discusses the role of compressed oops and MemberName vmtarget, and provides concrete fixes such as adjusting field writes or disabling pointer compression.

Big Data Technology & Architecture
Big Data Technology & Architecture
Big Data Technology & Architecture
Analyzing a JVM Crash Caused by Compressed Oops and MemberName vmtarget Mis‑handling

The crash report shows a JVM crash in the GC thread (GCTaskThread) with the problematic frame

# V  [libjvm.so+0x5bbf05]  instanceKlass::oop_follow_contents(ParCompactionManager*, oopDesc*)+0x2c5

, indicating the failure happened while the GC was processing an object.

Enabling the JVM verification flags -XX:+VerifyBeforeGC -XX:+VerifyAfterGC makes the VM abort on illegal object references and prints the offending addresses, e.g., Failed: 0x000000079ac5fe30 -> 0x0000000410bc55c0.

To investigate the core dump, the SA tool CLHSDB can be used from the command line: java -cp .:$JAVA_HOME/lib/sa-jdi.jar sun.jvm.hotspot.CLHSDB and then attach the dump:

java -cp .:$JAVA_HOME/lib/sa-jdi.jar sun.jvm.hotspot.CLHSDB $JAVA_HOME/bin/java 99083

Make sure the dump matches the JVM version and run as root.

Scanning the address near 0x000000079ac5fe30 reveals a MemberName object; the nearby 0x0000000782178ab8 is a method object. The failed address is the vmtarget field of the MemberName instance.

Since JDK 6 the VM uses compressed oops to save heap space. A compressed pointer stores the offset from a base address and a shift value; when the heap is below a threshold the base and shift become zero, effectively disabling compression. The printed address 0x0000000410bc55c0 is a compressed value that does not correspond to a real object, while the uncompressed address 0x0000000782178ab8 is valid.

The code that writes the target is:

void java_lang_invoke_MemberName::adjust_vmtarget(oop mname, oop ref) {
    mname->address_field_put(_vmtarget_offset, (address)ref);
}

During class redefinition, MemberNameTable::adjust_method_entries calls this function for each obsolete method.

Fixes include changing the write to use obj_field_put so the VM stores a proper compressed oop: mname->obj_field_put(_vmtarget_offset, new_method); Alternatively, avoid modifying MemberName during instrumentation or disable pointer compression with the JVM flag -XX:+UseCompressedOops (or the opposite flag to turn it off, depending on the JVM version).

Following these steps allows developers to locate the root cause of the crash and apply a reliable fix.

JavaJVMCrashAnalysisgcCLHSDBCompressedOopsSA
Big Data Technology & Architecture
Written by

Big Data Technology & Architecture

Wang Zhiwu, a big data expert, dedicated to sharing big data technology.

0 followers
Reader feedback

How this landed with the community

Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.