--- old/test/hotspot/jtreg/vmTestbase/nsk/jdi/ReferenceType/instances/instances003/instances003.java 2018-11-07 16:35:13.000000000 -0800 +++ new/test/hotspot/jtreg/vmTestbase/nsk/jdi/ReferenceType/instances/instances003/instances003.java 2018-11-07 16:35:12.000000000 -0800 @@ -62,6 +62,7 @@ import java.io.PrintStream; import java.util.*; +import com.sun.jdi.ObjectCollectedException; import com.sun.jdi.ObjectReference; import com.sun.jdi.ReferenceType; @@ -122,9 +123,10 @@ // create temporary strong references to prevent the weakly referred instances being GCed // during the time between creating them and disabling collection on them + boolean useTempStrongReference = needTempStongReference(referrerType); pipe.println(HeapwalkingDebuggee.COMMAND_CREATE_INSTANCES + ":" + className + ":" + createInstanceCount + - ":" + referrerCount + ":" + referrerType + - (referrerType.equals(ObjectInstancesManager.WEAK_REFERENCE) ? "|" + ObjectInstancesManager.STRONG_REFERENCE : "")); + ":" + referrerCount + ":" + referrerType + + (useTempStrongReference ? "|" + ObjectInstancesManager.STRONG_REFERENCE : "")); // Note! This test is broken, in the sense that it incorrectly assumes // that no GC can happen before it walks the heap. In practice, it seems @@ -135,14 +137,24 @@ checkDebugeeAnswer_instanceCounts(className, createInstanceCount, objectsToFilter); ReferenceType referenceType = debuggee.classByName(className); - List instances = HeapwalkingDebugger.filterObjectReferrence(objectsToFilter, referenceType.instances(0)); + List allInstances = HeapwalkingDebugger.filterObjectReferrence(objectsToFilter, referenceType.instances(0)); - for (ObjectReference or : instances) { - or.disableCollection(); + // There are potentially other non-test Java threads allocating objects and triggering GC's. + // We need to call disableCollection() on each object returned by referenceType.instances() + // to deal with the case when GC was triggered. Otherwise, these objects can + // be potentially collected. + List instances = new LinkedList<>(); + for (ObjectReference objRef : allInstances) { + try { + objRef.disableCollection(); + instances.add(objRef); + } catch (ObjectCollectedException ex) { + // skip this references + } } // remove the temporary strong references so the weak references can be properly tested - if (referrerType.equals(ObjectInstancesManager.WEAK_REFERENCE)) { + if (useTempStrongReference) { pipe.println(HeapwalkingDebuggee.COMMAND_DELETE_REFERRERS + ":" + className + ":" + referrerCount + ":" + ObjectInstancesManager.STRONG_REFERENCE); if (!isDebuggeeReady()) { return; @@ -157,6 +169,7 @@ instances.get(i).enableCollection(); } + pipe.println(HeapwalkingDebuggee.COMMAND_DELETE_INSTANCES + ":" + className + ":" + createInstanceCount); if (!isDebuggeeReady()) @@ -183,4 +196,13 @@ testClass(className, referenceType); } } + + + private static boolean needTempStongReference(String referenceType) { + return ObjectInstancesManager.WEAK_REFERENCE.equals(referenceType) || + ObjectInstancesManager.JNI_WEAK_REFERENCE.equals(referenceType) || + ObjectInstancesManager.PHANTOM_REFERENCE.equals(referenceType) || + ObjectInstancesManager.SOFT_REFERENCE.equals(referenceType); + + } }