Path: blob/master/test/hotspot/jtreg/gc/TestReferenceRefersTo.java
40930 views
/*1* Copyright (c) 2020, 2021, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation.7*8* This code is distributed in the hope that it will be useful, but WITHOUT9* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or10* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License11* version 2 for more details (a copy is included in the LICENSE file that12* accompanied this code).13*14* You should have received a copy of the GNU General Public License version15* 2 along with this work; if not, write to the Free Software Foundation,16* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.17*18* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA19* or visit www.oracle.com if you need additional information or have any20* questions.21*/2223package gc;2425/* @test26* @requires vm.gc != "Epsilon"27* @library /test/lib28* @build sun.hotspot.WhiteBox29* @run driver jdk.test.lib.helpers.ClassFileInstaller sun.hotspot.WhiteBox30* @run main/othervm31* -Xbootclasspath/a:.32* -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI33* gc.TestReferenceRefersTo34*/3536import java.lang.ref.PhantomReference;37import java.lang.ref.Reference;38import java.lang.ref.ReferenceQueue;39import java.lang.ref.WeakReference;40import sun.hotspot.WhiteBox;4142public class TestReferenceRefersTo {43private static final WhiteBox WB = WhiteBox.getWhiteBox();4445private static final class TestObject {46public final int value;4748public TestObject(int value) {49this.value = value;50}51}5253private static volatile TestObject testObjectNone = null;54private static volatile TestObject testObject1 = null;55private static volatile TestObject testObject2 = null;56private static volatile TestObject testObject3 = null;57private static volatile TestObject testObject4 = null;5859private static ReferenceQueue<TestObject> queue = null;6061private static PhantomReference<TestObject> testPhantom1 = null;6263private static WeakReference<TestObject> testWeak2 = null;64private static WeakReference<TestObject> testWeak3 = null;65private static WeakReference<TestObject> testWeak4 = null;6667private static void setup() {68testObjectNone = new TestObject(0);69testObject1 = new TestObject(1);70testObject2 = new TestObject(2);71testObject3 = new TestObject(3);72testObject4 = new TestObject(4);7374queue = new ReferenceQueue<TestObject>();7576testPhantom1 = new PhantomReference<TestObject>(testObject1, queue);7778testWeak2 = new WeakReference<TestObject>(testObject2, queue);79testWeak3 = new WeakReference<TestObject>(testObject3, queue);80testWeak4 = new WeakReference<TestObject>(testObject4, queue);81}8283private static void gcUntilOld(Object o) throws Exception {84if (!WB.isObjectInOldGen(o)) {85WB.fullGC();86if (!WB.isObjectInOldGen(o)) {87fail("object not promoted by full gc");88}89}90}9192private static void gcUntilOld() throws Exception {93gcUntilOld(testObjectNone);94gcUntilOld(testObject1);95gcUntilOld(testObject2);96gcUntilOld(testObject3);97gcUntilOld(testObject4);9899gcUntilOld(testPhantom1);100101gcUntilOld(testWeak2);102gcUntilOld(testWeak3);103gcUntilOld(testWeak4);104}105106private static void progress(String msg) {107System.out.println(msg);108}109110private static void fail(String msg) throws Exception {111throw new RuntimeException(msg);112}113114private static void expectCleared(Reference<TestObject> ref,115String which) throws Exception {116expectNotValue(ref, testObjectNone, which);117if (!ref.refersTo(null)) {118fail("expected " + which + " to be cleared");119}120}121122private static void expectNotCleared(Reference<TestObject> ref,123String which) throws Exception {124expectNotValue(ref, testObjectNone, which);125if (ref.refersTo(null)) {126fail("expected " + which + " to not be cleared");127}128}129130private static void expectValue(Reference<TestObject> ref,131TestObject value,132String which) throws Exception {133expectNotValue(ref, testObjectNone, which);134expectNotCleared(ref, which);135if (!ref.refersTo(value)) {136fail(which + " doesn't refer to expected value");137}138}139140private static void expectNotValue(Reference<TestObject> ref,141TestObject value,142String which) throws Exception {143if (ref.refersTo(value)) {144fail(which + " refers to unexpected value");145}146}147148private static void checkInitialStates() throws Exception {149expectValue(testPhantom1, testObject1, "testPhantom1");150expectValue(testWeak2, testObject2, "testWeak2");151expectValue(testWeak3, testObject3, "testWeak3");152expectValue(testWeak4, testObject4, "testWeak4");153}154155private static void discardStrongReferences() {156// testObjectNone not dropped157testObject1 = null;158testObject2 = null;159// testObject3 not dropped160testObject4 = null;161}162163private static void testConcurrentCollection() throws Exception {164progress("setup concurrent collection test");165setup();166progress("gcUntilOld");167gcUntilOld();168169progress("acquire control of concurrent cycles");170WB.concurrentGCAcquireControl();171try {172progress("check initial states");173checkInitialStates();174175progress("discard strong references");176discardStrongReferences();177178progress("run GC to before marking completed");179WB.concurrentGCRunTo(WB.BEFORE_MARKING_COMPLETED);180181progress("fetch test objects, possibly keeping some alive");182expectNotCleared(testPhantom1, "testPhantom1");183expectNotCleared(testWeak2, "testWeak2");184expectValue(testWeak3, testObject3, "testWeak3");185186// For some collectors, calling get() will keep testObject4 alive.187if (testWeak4.get() == null) {188fail("testWeak4 unexpectedly == null");189}190191progress("finish collection");192WB.concurrentGCRunToIdle();193194progress("verify expected clears");195expectCleared(testPhantom1, "testPhantom1");196expectCleared(testWeak2, "testWeak2");197expectValue(testWeak3, testObject3, "testWeak3");198199progress("verify get returns expected values");200if (testWeak2.get() != null) {201fail("testWeak2.get() != null");202}203204TestObject obj3 = testWeak3.get();205if (obj3 == null) {206fail("testWeak3.get() returned null");207} else if (obj3.value != 3) {208fail("testWeak3.get().value is " + obj3.value);209}210211TestObject obj4 = testWeak4.get();212213progress("verify queue entries");214long timeout = 60000; // 1 minute of milliseconds.215while (true) {216Reference<? extends TestObject> ref = queue.remove(timeout);217if (ref == null) {218break;219} else if (ref == testPhantom1) {220testPhantom1 = null;221} else if (ref == testWeak2) {222testWeak2 = null;223} else if (ref == testWeak3) {224testWeak3 = null;225} else if (ref == testWeak4) {226testWeak4 = null;227} else {228fail("unexpected reference in queue");229}230}231if (testPhantom1 != null) {232fail("testPhantom1 not notified");233} else if (testWeak2 != null) {234fail("testWeak2 not notified");235} else if (testWeak3 == null) {236fail("testWeak3 notified");237}238if ((testWeak4 == null) != (obj4 == null)) {239fail("either referent is cleared and we got notified, or neither of this happened: referent: "240+ obj4 + ", notified: " + (testWeak4 == null));241}242243} finally {244progress("release control of concurrent cycles");245WB.concurrentGCReleaseControl();246}247progress("finished concurrent collection test");248}249250private static void testSimpleCollection() throws Exception {251progress("setup simple collection test");252setup();253progress("gcUntilOld");254gcUntilOld();255256progress("check initial states");257checkInitialStates();258259progress("discard strong references");260TestObject tw4 = testWeak4.get(); // Keep testObject4 alive.261discardStrongReferences();262263progress("collect garbage");264WB.fullGC();265266progress("verify expected clears");267expectCleared(testPhantom1, "testPhantom1");268expectCleared(testWeak2, "testWeak2");269expectValue(testWeak3, testObject3, "testWeak3");270expectNotCleared(testWeak4, "testWeak4");271272progress("verify get returns expected values");273if (testWeak2.get() != null) {274fail("testWeak2.get() != null");275} else if (testWeak3.get() != testObject3) {276fail("testWeak3.get() is not expected value");277} else if (testWeak4.get() != tw4) {278fail("testWeak4.get() is not expected value");279}280281progress("finished simple collection test");282}283284public static void main(String[] args) throws Exception {285if (WB.supportsConcurrentGCBreakpoints()) {286testConcurrentCollection();287}288testSimpleCollection();289}290}291292293