// resolve controls whether getObject returns an explicitly // resolved jweak value (when resolve is true), or returns the // jweak directly and invokes the implicit resolution in the // native call return value handling path (when resolve is false). privateboolean resolve = true;
// Create the test object and record it both strongly and weakly. privatevoid remember(int value) {
TestObject o = new TestObject(value);
registerObject(o);
testObject = o;
}
// Remove both strong and weak references to the current test object. privatevoid forget() {
unregisterObject();
testObject = null;
}
// Repeatedly perform full GC until o is in the old generation. privatevoid gcUntilOld(Object o) { while (!WB.isObjectInOldGen(o)) {
WB.fullGC();
}
}
// Verify the weakly recorded object privatevoid checkValue(int value) throws Exception {
Object o = getObject(); if (o == null) { thrownew RuntimeException("Weak reference unexpectedly null");
}
TestObject t = (TestObject)o; if (t.value != value) { thrownew RuntimeException("Incorrect value");
}
}
// Verify we can create a weak reference and get it back. privatevoid checkSanity() throws Exception {
System.out.println("running checkSanity"); try { // Inhibit concurrent GC during this check.
WB.concurrentGCAcquireControl();
int value = 5; try {
remember(value);
checkValue(value);
} finally {
forget();
}
} finally {
WB.concurrentGCReleaseControl();
}
}
// Verify weak ref value survives across collection if strong ref exists. privatevoid checkSurvival() throws Exception {
System.out.println("running checkSurvival"); try { int value = 10; try {
remember(value);
checkValue(value);
gcUntilOld(testObject); // Run a concurrent collection after object is old.
WB.concurrentGCAcquireControl();
WB.concurrentGCRunTo(WB.AFTER_MARKING_STARTED);
WB.concurrentGCRunToIdle(); // Verify weak ref still has expected value.
checkValue(value);
} finally {
forget();
}
} finally {
WB.concurrentGCReleaseControl();
}
}
// Verify weak ref cleared if no strong ref exists. privatevoid checkClear() throws Exception {
System.out.println("running checkClear"); try { int value = 15; try {
remember(value);
checkValue(value);
gcUntilOld(testObject); // Run a concurrent collection after object is old.
WB.concurrentGCAcquireControl();
WB.concurrentGCRunTo(WB.AFTER_MARKING_STARTED);
WB.concurrentGCRunToIdle();
checkValue(value);
testObject = null; // Run a concurrent collection after strong ref removed.
WB.concurrentGCRunTo(WB.AFTER_MARKING_STARTED);
WB.concurrentGCRunToIdle(); // Verify weak ref cleared as expected.
Object recorded = getObject(); if (recorded != null) { thrownew RuntimeException("expected clear");
}
} finally {
forget();
}
} finally {
WB.concurrentGCReleaseControl();
}
}
// Verify weak ref not cleared if no strong ref at start of // collection but weak ref read during marking. privatevoid checkShouldNotClear() throws Exception {
System.out.println("running checkShouldNotClear"); try { int value = 20; try {
remember(value);
checkValue(value);
gcUntilOld(testObject); // Block concurrent cycle until we're ready.
WB.concurrentGCAcquireControl();
checkValue(value);
testObject = null; // Discard strong ref // Run through most of marking
WB.concurrentGCRunTo(WB.BEFORE_MARKING_COMPLETED); // Fetch weak ref'ed object. Should be kept alive now.
Object recovered = getObject(); if (recovered == null) { thrownew RuntimeException("unexpected clear during mark");
} // Finish collection, including reference processing. // Block any further cycles while we finish check.
WB.concurrentGCRunToIdle(); // Fetch weak ref'ed object. Referent is manifestly // live in recovered; the earlier fetch should have // kept it alive through collection, so weak ref // should not have been cleared. if (getObject() == null) { // 8166188 problem results in not doing the // keep-alive of earlier getObject result, so // recovered is now reachable but not marked. // We may eventually crash. thrownew RuntimeException("cleared jweak for live object");
}
Reference.reachabilityFence(recovered);
} finally {
forget();
}
} finally {
WB.concurrentGCReleaseControl();
}
}
publicstaticvoid main(String[] args) throws Exception { if (!WB.supportsConcurrentGCBreakpoints()) { thrownew SkippedException(
GC.selected().name() + " doesn't support concurrent GC breakpoints");
}
// Perform check with direct jweak resolution.
System.out.println("Check with jweak resolved"); new TestJNIWeak(true).check();
// Perform check with implicit jweak resolution by native // call's return value handling.
System.out.println("Check with jweak returned"); new TestJNIWeak(false).check();
}
}
Messung V0.5 in Prozent
¤ Dauer der Verarbeitung: 0.16 Sekunden
(vorverarbeitet am 2026-06-10)
¤
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.