JDK-8159127 : hprof heap dumps broken for lambda classdata
  • Type: Bug
  • Component: hotspot
  • Sub-Component: svc-agent
  • Affected Version: 8u60,9
  • Priority: P3
  • Status: Resolved
  • Resolution: Fixed
  • OS: generic
  • CPU: x86_64
  • Submitted: 2016-06-07
  • Updated: 2019-07-03
  • Resolved: 2016-12-20
The Version table provides details related to the release that this issue/RFE will be addressed.

Unresolved : Release in which this issue/RFE will be addressed.
Resolved: Release in which this issue/RFE has been resolved.
Fixed : Release in which this issue/RFE has been fixed. The release containing this fix may be available for download as an Early Access Release or a General Availability Release.

To download the current JDK release, click here.
JDK 9
9 b151Fixed
Related Reports
Relates :  
Relates :  
Description
FULL PRODUCT VERSION :
$ java -version
java version "1.8.0_60"
Java(TM) SE Runtime Environment (build 1.8.0_60-b27)
Java HotSpot(TM) 64-Bit Server VM (build 25.60-b23, mixed mode)

ADDITIONAL OS VERSION INFORMATION :
$ uname -a
SunOS solaris 5.11 11.2 i86pc i386 i86pc

$ uname -a
Linux version 2.6.32-504.el6.x86_64

64 Bit linux (No longer have access to machine)

A DESCRIPTION OF THE PROBLEM :
Here is a minimal test case running on Oracle Solaris:

$ uname -a
SunOS solaris 5.11 11.2 i86pc i386 i86pc
$ java -version
java version "1.8.0_60-ea"
Java(TM) SE Runtime Environment (build 1.8.0_60-ea-b25)
Java HotSpot(TM) 64-Bit Server VM (build 25.60-b23, mixed mode)
$ cat LambdaSleep.java
import java.util.Arrays;

public class LambdaSleep {
    public static void main(String[] args) throws InterruptedException {
String[] words = new String[] { "longer", "short" };
Arrays.sort(words, (first, second) ->
Integer.compare(first.length(), second.length()));
Thread.sleep(300000);
    }
}
$ javac LambdaSleep.java
$ java LambdaSleep &
[1] 4528

I took two hprof heap dumps of this program. The first, live4528.hprof, comes
from the live process:

$ jmap -dump:format=b,file=live4528.hprof 4528
Dumping heap to /export/home/basil/live4528.hprof ...
Heap dump file created

The second, core4528.hprof, comes from a core dump:

$ gcore 4528
gcore: core.4528 dumped
$ jmap -dump:format=b,file=core4528.hprof /opt/jdk/bin/java core.4528
Attaching to core core.4528 from executable /opt/jdk/bin/java, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.60-b23
Dumping heap to core4528.hprof ...
Heap dump file created

With the fix for JDK-8044416 in place, the heap dump is generated without any
exceptions (which is an improvement), but it is still not usable in any
meaningful way.

While live4528.hprof loads in Eclipse MAT, core4528.hprof fails to load in
Eclipse MAT with the following exception:

!ENTRY org.eclipse.core.jobs 4 2 2015-08-06 08:32:45.883
!MESSAGE An internal error occurred during: "Parsing heap dump from
'core4528.hprof'".
!STACK 0
java.lang.NullPointerException
at org.eclipse.mat.hprof.HprofParserHandlerImpl.resolveClassHierarchy(HprofParserHandlerImpl.java:587)
at org.eclipse.mat.hprof.Pass2Parser.readInstanceDump(Pass2Parser.java:205)
at org.eclipse.mat.hprof.Pass2Parser.readDumpSegments(Pass2Parser.java:159)
at org.eclipse.mat.hprof.Pass2Parser.read(Pass2Parser.java:89)
at org.eclipse.mat.hprof.HprofIndexBuilder.fill(HprofIndexBuilder.java:94)
at org.eclipse.mat.parser.internal.SnapshotFactoryImpl.parse(SnapshotFactoryImpl.java:222)
at org.eclipse.mat.parser.internal.SnapshotFactoryImpl.openSnapshot(SnapshotFactoryImpl.java:126)
at org.eclipse.mat.snapshot.SnapshotFactory.openSnapshot(SnapshotFactory.java:145)
at org.eclipse.mat.ui.snapshot.ParseHeapDumpJob.run(ParseHeapDumpJob.java:83)
at org.eclipse.core.internal.jobs.Worker.run(Worker.java:55)

While both live4528.hprof and core4528.hprof load in VisualVM, attempting to
find objects by retained size in VisualVM hangs on "Computing retained
sizes..." for core4528.hprof, while this operation succeeds for
live4528.hprof.

When lambdas are not in use, the above problem is not manifest. Clearly there
is a difference in the hprof heap dump generated from the core file compared
to the one generated from the live process.

This bug is also captured by Eclipse bug 476262 [1]. According to the comments
on this bug, this error is reproducible on Windows (version unspecified).

According to a stack overflow question [2], this bug has also been encountered
on Linux version 2.6.32-504.el6.x86_64.

[1] https://bugs.eclipse.org/bugs/show_bug.cgi?id=476262
[2] https://stackoverflow.com/questions/34719148/mat-cant-open-the-dump-file

REGRESSION.  Last worked in version 7u76

ADDITIONAL REGRESSION INFORMATION: 
$ /opt/jdk/bin/java -version
java version "1.7.0_65"
Java(TM) SE Runtime Environment (build 1.7.0_65-b17)
Java HotSpot(TM) Server VM (build 24.65-b04, mixed mode)

STEPS TO FOLLOW TO REPRODUCE THE PROBLEM :
Here is a minimal test case running on Oracle Solaris:

$ uname -a
SunOS solaris 5.11 11.2 i86pc i386 i86pc
$ java -version
java version "1.8.0_60-ea"
Java(TM) SE Runtime Environment (build 1.8.0_60-ea-b25)
Java HotSpot(TM) 64-Bit Server VM (build 25.60-b23, mixed mode)
$ cat LambdaSleep.java
import java.util.Arrays;

public class LambdaSleep {
    public static void main(String[] args) throws InterruptedException {
String[] words = new String[] { "longer", "short" };
Arrays.sort(words, (first, second) ->
Integer.compare(first.length(), second.length()));
Thread.sleep(300000);
    }
}
$ javac LambdaSleep.java
$ java LambdaSleep &
[1] 4528

I took two hprof heap dumps of this program. The first, live4528.hprof, comes
from the live process:

$ jmap -dump:format=b,file=live4528.hprof 4528
Dumping heap to /export/home/basil/live4528.hprof ...
Heap dump file created

The second, core4528.hprof, comes from a core dump:

$ gcore 4528
gcore: core.4528 dumped
$ jmap -dump:format=b,file=core4528.hprof /opt/jdk/bin/java core.4528
Attaching to core core.4528 from executable /opt/jdk/bin/java, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.60-b23
Dumping heap to core4528.hprof ...
Heap dump file created

With the fix for JDK-8044416 in place, the heap dump is generated without any
exceptions (which is an improvement), but it is still not usable in any
meaningful way.

While live4528.hprof loads in Eclipse MAT, core4528.hprof fails to load in
Eclipse MAT with the following exception:

!ENTRY org.eclipse.core.jobs 4 2 2015-08-06 08:32:45.883
!MESSAGE An internal error occurred during: "Parsing heap dump from
'core4528.hprof'".
!STACK 0
java.lang.NullPointerException
at org.eclipse.mat.hprof.HprofParserHandlerImpl.resolveClassHierarchy(HprofParserHandlerImpl.java:587)
at org.eclipse.mat.hprof.Pass2Parser.readInstanceDump(Pass2Parser.java:205)
at org.eclipse.mat.hprof.Pass2Parser.readDumpSegments(Pass2Parser.java:159)
at org.eclipse.mat.hprof.Pass2Parser.read(Pass2Parser.java:89)
at org.eclipse.mat.hprof.HprofIndexBuilder.fill(HprofIndexBuilder.java:94)
at org.eclipse.mat.parser.internal.SnapshotFactoryImpl.parse(SnapshotFactoryImpl.java:222)
at org.eclipse.mat.parser.internal.SnapshotFactoryImpl.openSnapshot(SnapshotFactoryImpl.java:126)
at org.eclipse.mat.snapshot.SnapshotFactory.openSnapshot(SnapshotFactory.java:145)
at org.eclipse.mat.ui.snapshot.ParseHeapDumpJob.run(ParseHeapDumpJob.java:83)
at org.eclipse.core.internal.jobs.Worker.run(Worker.java:55)

While both live4528.hprof and core4528.hprof load in VisualVM, attempting to
find objects by retained size in VisualVM hangs on "Computing retained
sizes..." for core4528.hprof, while this operation succeeds for
live4528.hprof.

When lambdas are not in use, the above problem is not manifest. Clearly there
is a difference in the hprof heap dump generated from the core file compared
to the one generated from the live process.

EXPECTED VERSUS ACTUAL BEHAVIOR :
EXPECTED -
The expected result is that an hprof generated from a core file of a Java 8 program utilizing lambdas would load in Eclipse MAT without throwing an exception. Additionally, VisualVM should be able to calculate the retained sizes for Java objects using the hprof.
ACTUAL -
The hprof of the given Java 8 program, generated from a
core file, fails to load in Eclipse MAT with the following exception:

!ENTRY org.eclipse.core.jobs 4 2 2015-08-06 08:32:45.883
!MESSAGE An internal error occurred during: "Parsing heap dump from
'core4528.hprof'".
!STACK 0
java.lang.NullPointerException
at org.eclipse.mat.hprof.HprofParserHandlerImpl.resolveClassHierarchy(HprofParserHandlerImpl.java:587)
at org.eclipse.mat.hprof.Pass2Parser.readInstanceDump(Pass2Parser.java:205)
at org.eclipse.mat.hprof.Pass2Parser.readDumpSegments(Pass2Parser.java:159)
at org.eclipse.mat.hprof.Pass2Parser.read(Pass2Parser.java:89)
at org.eclipse.mat.hprof.HprofIndexBuilder.fill(HprofIndexBuilder.java:94)
at org.eclipse.mat.parser.internal.SnapshotFactoryImpl.parse(SnapshotFactoryImpl.java:222)
at org.eclipse.mat.parser.internal.SnapshotFactoryImpl.openSnapshot(SnapshotFactoryImpl.java:126)
at org.eclipse.mat.snapshot.SnapshotFactory.openSnapshot(SnapshotFactory.java:145)
at org.eclipse.mat.ui.snapshot.ParseHeapDumpJob.run(ParseHeapDumpJob.java:83)
at org.eclipse.core.internal.jobs.Worker.run(Worker.java:55)

VisualVM hangs on "Computing retained sizes..."

ERROR MESSAGES/STACK TRACES THAT OCCUR :
From Eclipse MAT:


!ENTRY org.eclipse.core.jobs 4 2 2015-08-06 08:32:45.883
!MESSAGE An internal error occurred during: "Parsing heap dump from
'core4528.hprof'".
!STACK 0
java.lang.NullPointerException
at org.eclipse.mat.hprof.HprofParserHandlerImpl.resolveClassHierarchy(HprofParserHandlerImpl.java:587)
at org.eclipse.mat.hprof.Pass2Parser.readInstanceDump(Pass2Parser.java:205)
at org.eclipse.mat.hprof.Pass2Parser.readDumpSegments(Pass2Parser.java:159)
at org.eclipse.mat.hprof.Pass2Parser.read(Pass2Parser.java:89)
at org.eclipse.mat.hprof.HprofIndexBuilder.fill(HprofIndexBuilder.java:94)
at org.eclipse.mat.parser.internal.SnapshotFactoryImpl.parse(SnapshotFactoryImpl.java:222)
at org.eclipse.mat.parser.internal.SnapshotFactoryImpl.openSnapshot(SnapshotFactoryImpl.java:126)
at org.eclipse.mat.snapshot.SnapshotFactory.openSnapshot(SnapshotFactory.java:145)
at org.eclipse.mat.ui.snapshot.ParseHeapDumpJob.run(ParseHeapDumpJob.java:83)
at org.eclipse.core.internal.jobs.Worker.run(Worker.java:55)

REPRODUCIBILITY :
This bug can be reproduced always.

---------- BEGIN SOURCE ----------
import java.util.Arrays;

public class LambdaSleep {
    public static void main(String[] args) throws InterruptedException {
String[] words = new String[] { "longer", "short" };
Arrays.sort(words, (first, second) ->
Integer.compare(first.length(), second.length()));
Thread.sleep(300000);
    }
}
---------- END SOURCE ----------

CUSTOMER SUBMITTED WORKAROUND :
There does not appear to be a workaround for this bug.


Comments
There was an attempt to backport it to 8u: https://mail.openjdk.java.net/pipermail/jdk8u-dev/2019-April/009216.html
03-07-2019

The exception was caused by class dump records not being found for lambda related anonymous classes since these are not present in the system dictionary. The proposed fix here is to have another round to dump class dump records after we go through the klasses in the system dictionary, but this time by iterating only through the anonymous klasses in the class loader graph.
12-12-2016

I've been able to produce the same. I've hit the "Computing retained sizes" hang issue in jvisualvm a few times now. parsing a non-lambda class equivalent works ok : /tmp/hprof_test$ more NonLambdaSleep.java import java.util.Arrays; public class NonLambdaSleep { public static void main(String[] args) throws InterruptedException { String[] words = new String[] { "longer", "short" }; Arrays.sort(words, new java.util.Comparator<String>() { public int compare(String first, String second){ return Integer.compare(first.length(), second.length()); } }); Thread.sleep(300000); } } I'm attaching two heap dumps obtained from the jvisualvm process while the "computing retained sizes" operation was seen to be hanging. This was tested with 8u92.
06-07-2016

This is an regression introduced in 8u60. 8u45 - Pass 8u60 - Fail 8u92 - Fail 9 ea b121- Fail == !ENTRY org.eclipse.e4.ui.workbench 4 0 2016-06-09 11:43:33.096 !MESSAGE !STACK 0 java.lang.NullPointerException at org.eclipse.jface.resource.JFaceResources.getResources(JFaceResources.java:209) at org.eclipse.jface.resource.JFaceResources.getResources(JFaceResources.java:230) at org.eclipse.ui.part.WorkbenchPart.dispose(WorkbenchPart.java:109) at org.eclipse.jdt.internal.ui.packageview.PackageExplorerPart.dispose(PackageExplorerPart.java:472) at org.eclipse.ui.internal.e4.compatibility.CompatibilityPart.invalidate(CompatibilityPart.java:238) at org.eclipse.ui.internal.e4.compatibility.CompatibilityPart.destroy(CompatibilityPart.java:394) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) at java.lang.reflect.Method.invoke(Method.java:606) at org.eclipse.e4.core.internal.di.MethodRequestor.execute(MethodRequestor.java:56) at org.eclipse.e4.core.internal.di.InjectorImpl.processAnnotated(InjectorImpl.java:898) at org.eclipse.e4.core.internal.di.InjectorImpl.processAnnotated(InjectorImpl.java:879) at org.eclipse.e4.core.internal.di.InjectorImpl.disposed(InjectorImpl.java:398) at org.eclipse.e4.core.internal.di.Requestor.disposed(Requestor.java:148) at org.eclipse.e4.core.internal.contexts.ContextObjectSupplier$ContextInjectionListener.update(ContextObjectSupplier.java:78) at org.eclipse.e4.core.internal.contexts.TrackableComputationExt.update(TrackableComputationExt.java:111) at org.eclipse.e4.core.internal.contexts.TrackableComputationExt.handleInvalid(TrackableComputationExt.java:74) at org.eclipse.e4.core.internal.contexts.EclipseContext.dispose(EclipseContext.java:174) at org.eclipse.e4.core.internal.contexts.EclipseContext.dispose(EclipseContext.java:159) at org.eclipse.e4.core.internal.contexts.EclipseContext.dispose(EclipseContext.java:159) at org.eclipse.e4.core.internal.contexts.EclipseContext.dispose(EclipseContext.java:159) at org.eclipse.e4.core.internal.contexts.EclipseContext.dispose(EclipseContext.java:159) at org.eclipse.e4.core.internal.contexts.osgi.EclipseContextOSGi.dispose(EclipseContextOSGi.java:106) at org.eclipse.e4.core.internal.contexts.osgi.EclipseContextOSGi.bundleChanged(EclipseContextOSGi.java:139) at org.eclipse.osgi.internal.framework.BundleContextImpl.dispatchEvent(BundleContextImpl.java:902) at org.eclipse.osgi.framework.eventmgr.EventManager.dispatchEvent(EventManager.java:230) at org.eclipse.osgi.framework.eventmgr.ListenerQueue.dispatchEventSynchronous(ListenerQueue.java:148) at org.eclipse.osgi.internal.framework.EquinoxEventPublisher.publishBundleEventPrivileged(EquinoxEventPublisher.java:165) at org.eclipse.osgi.internal.framework.EquinoxEventPublisher.publishBundleEvent(EquinoxEventPublisher.java:75) at org.eclipse.osgi.internal.framework.EquinoxEventPublisher.publishBundleEvent(EquinoxEventPublisher.java:67) at org.eclipse.osgi.internal.framework.EquinoxContainerAdaptor.publishModuleEvent(EquinoxContainerAdaptor.java:102) at org.eclipse.osgi.container.Module.publishEvent(Module.java:466) at org.eclipse.osgi.container.Module.doStop(Module.java:624) at org.eclipse.osgi.container.Module.stop(Module.java:488) at org.eclipse.osgi.container.SystemModule.stop(SystemModule.java:186) at org.eclipse.osgi.internal.framework.EquinoxBundle$SystemBundle$EquinoxSystemModule$1.run(EquinoxBundle.java:159) at java.lang.Thread.run(Thread.java:745)
09-06-2016