3232import static org .junit .Assert .assertFalse ;
3333import static org .junit .Assert .assertNotNull ;
3434import static org .junit .Assert .assertNull ;
35+ import static org .junit .Assert .assertTrue ;
3536import org .junit .Test ;
3637import org .netbeans .lib .profiler .heap .HeapUtils .HprofGenerator ;
3738
@@ -47,26 +48,64 @@ public void singleObjectMultipleSegments() throws IOException {
4748 }
4849
4950 @ Test
50- public void unresolvedStickyClassRootDoesNotBreakGCRootLookup () throws IOException {
51+ public void stickyClassRootKeepsStaticReferencesReachable () throws IOException {
5152 File mydump = File .createTempFile ("mydump" , ".hprof" );
53+ final int [] targetId = new int [1 ];
5254 try (HprofGenerator gen = new HprofGenerator (new FileOutputStream (mydump ))) {
5355 gen .writeHeapSegment (new HprofGenerator .Generator <HprofGenerator .HeapSegment >() {
5456 @ Override
5557 public void generate (HprofGenerator .HeapSegment seg ) throws IOException {
58+ seg .newClass ("java.lang.Class" ).dumpClass ();
5659 seg .newClass ("com.oracle.svm.core.heap.heapImpl.DiscoverableReference" )
5760 .addField ("rawReferent" , Object .class )
5861 .dumpClass ();
59- HprofGenerator .ClassInstance clazz = seg .newClass ("text.HelloWorld" ).dumpClass ();
60- seg .dumpStickyClassRoot (clazz );
61- seg .dumpInstance (clazz );
62+ HprofGenerator .ClassInstance targetClass = seg .newClass ("text.Target" ).dumpClass ();
63+ targetId [0 ] = seg .dumpInstance (targetClass );
64+ HprofGenerator .ClassInstance rootClass = seg .newClass ("text.Root" )
65+ .addStaticObjectField ("target" , targetId [0 ])
66+ .dumpClass ();
67+ seg .dumpStickyClassRoot (rootClass );
68+ }
69+ }, true );
70+ }
71+
72+ Heap heap = HeapFactory .createHeap (mydump );
73+ assertEquals ("One sticky class root" , 1 , heap .getGCRoots ().size ());
74+ GCRoot root = (GCRoot ) heap .getGCRoots ().iterator ().next ();
75+ Instance rootInstance = root .getInstance ();
76+ assertTrue ("Class object instance" , rootInstance instanceof ClassDumpInstance );
77+ assertEquals ("Root found by class object ID" , root , heap .getGCRoot (rootInstance ));
78+
79+ Instance target = heap .getInstanceByID (targetId [0 ]);
80+ assertNotNull ("Static field target" , target );
81+ heap .getBiggestObjectsByRetainedSize (1 );
82+ assertEquals ("Target reached from sticky class" , rootInstance , target .getNearestGCRootPointer ());
83+ assertTrue ("Sticky class retains its static target" , rootInstance .getRetainedSize () > rootInstance .getSize ());
84+ }
85+
86+ @ Test
87+ public void unresolvedStickyClassRootDoesNotBreakRetainedSize () throws IOException {
88+ File mydump = File .createTempFile ("mydump" , ".hprof" );
89+ try (HprofGenerator gen = new HprofGenerator (new FileOutputStream (mydump ))) {
90+ gen .writeHeapSegment (new HprofGenerator .Generator <HprofGenerator .HeapSegment >() {
91+ @ Override
92+ public void generate (HprofGenerator .HeapSegment seg ) throws IOException {
93+ seg .newClass ("java.lang.Class" ).dumpClass ();
94+ seg .newClass ("com.oracle.svm.core.heap.heapImpl.DiscoverableReference" )
95+ .addField ("rawReferent" , Object .class )
96+ .dumpClass ();
97+ HprofGenerator .ClassInstance ordinaryClass = seg .newClass ("text.Ordinary" ).dumpClass ();
98+ seg .dumpInstance (ordinaryClass );
99+ seg .dumpStickyClassRoot (Integer .MAX_VALUE );
62100 }
63101 }, true );
64102 }
65103
66104 Heap heap = HeapFactory .createHeap (mydump );
67105 assertEquals ("One unresolved sticky class root" , 1 , heap .getGCRoots ().size ());
68- Instance instance = (Instance ) heap .getJavaClassByName ("text.HelloWorld" ).getInstances ().iterator ().next ();
69- assertNull ("Non-root instance" , heap .getGCRoot (instance ));
106+ GCRoot root = (GCRoot ) heap .getGCRoots ().iterator ().next ();
107+ assertNull ("No heap object for unresolved root" , root .getInstance ());
108+ assertNotNull ("Retained-size computation completes" , heap .getBiggestObjectsByRetainedSize (1 ));
70109 }
71110
72111 private static void singleObject (boolean flush ) throws IOException {
0 commit comments