jdk

Форк
0
/
TestReferenceRefersTo.java 
291 строка · 10.1 Кб
1
/*
2
 * Copyright (c) 2020, 2022, Oracle and/or its affiliates. All rights reserved.
3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4
 *
5
 * This code is free software; you can redistribute it and/or modify it
6
 * under the terms of the GNU General Public License version 2 only, as
7
 * published by the Free Software Foundation.
8
 *
9
 * This code is distributed in the hope that it will be useful, but WITHOUT
10
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
12
 * version 2 for more details (a copy is included in the LICENSE file that
13
 * accompanied this code).
14
 *
15
 * You should have received a copy of the GNU General Public License version
16
 * 2 along with this work; if not, write to the Free Software Foundation,
17
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
18
 *
19
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
20
 * or visit www.oracle.com if you need additional information or have any
21
 * questions.
22
 */
23

24
package gc;
25

26
/* @test
27
 * @requires vm.gc != "Epsilon"
28
 * @library /test/lib
29
 * @build jdk.test.whitebox.WhiteBox
30
 * @run driver jdk.test.lib.helpers.ClassFileInstaller jdk.test.whitebox.WhiteBox
31
 * @run main/othervm
32
 *      -Xbootclasspath/a:.
33
 *      -XX:+UnlockDiagnosticVMOptions -XX:+WhiteBoxAPI
34
 *      gc.TestReferenceRefersTo
35
 */
36

37
import java.lang.ref.PhantomReference;
38
import java.lang.ref.Reference;
39
import java.lang.ref.ReferenceQueue;
40
import java.lang.ref.WeakReference;
41
import jdk.test.whitebox.WhiteBox;
42

43
public class TestReferenceRefersTo {
44
    private static final WhiteBox WB = WhiteBox.getWhiteBox();
45

46
    private static final class TestObject {
47
        public final int value;
48

49
        public TestObject(int value) {
50
            this.value = value;
51
        }
52
    }
53

54
    private static volatile TestObject testObjectNone = null;
55
    private static volatile TestObject testObject1 = null;
56
    private static volatile TestObject testObject2 = null;
57
    private static volatile TestObject testObject3 = null;
58
    private static volatile TestObject testObject4 = null;
59

60
    private static ReferenceQueue<TestObject> queue = null;
61

62
    private static PhantomReference<TestObject> testPhantom1 = null;
63

64
    private static WeakReference<TestObject> testWeak2 = null;
65
    private static WeakReference<TestObject> testWeak3 = null;
66
    private static WeakReference<TestObject> testWeak4 = null;
67

68
    private static void setup() {
69
        testObjectNone = new TestObject(0);
70
        testObject1 = new TestObject(1);
71
        testObject2 = new TestObject(2);
72
        testObject3 = new TestObject(3);
73
        testObject4 = new TestObject(4);
74

75
        queue = new ReferenceQueue<TestObject>();
76

77
        testPhantom1 = new PhantomReference<TestObject>(testObject1, queue);
78

79
        testWeak2 = new WeakReference<TestObject>(testObject2, queue);
80
        testWeak3 = new WeakReference<TestObject>(testObject3, queue);
81
        testWeak4 = new WeakReference<TestObject>(testObject4, queue);
82
    }
83

84
    private static void gcUntilOld(Object o) throws Exception {
85
        if (!WB.isObjectInOldGen(o)) {
86
            WB.fullGC();
87
            if (!WB.isObjectInOldGen(o)) {
88
                fail("object not promoted by full gc");
89
            }
90
        }
91
    }
92

93
    private static void gcUntilOld() throws Exception {
94
        gcUntilOld(testObjectNone);
95
        gcUntilOld(testObject1);
96
        gcUntilOld(testObject2);
97
        gcUntilOld(testObject3);
98
        gcUntilOld(testObject4);
99

100
        gcUntilOld(testPhantom1);
101

102
        gcUntilOld(testWeak2);
103
        gcUntilOld(testWeak3);
104
        gcUntilOld(testWeak4);
105
    }
106

107
    private static void progress(String msg) {
108
        System.out.println(msg);
109
    }
110

111
    private static void fail(String msg) throws Exception {
112
        throw new RuntimeException(msg);
113
    }
114

115
    private static void expectCleared(Reference<TestObject> ref,
116
                                      String which) throws Exception {
117
        expectNotValue(ref, testObjectNone, which);
118
        if (!ref.refersTo(null)) {
119
            fail("expected " + which + " to be cleared");
120
        }
121
    }
122

123
    private static void expectNotCleared(Reference<TestObject> ref,
124
                                         String which) throws Exception {
125
        expectNotValue(ref, testObjectNone, which);
126
        if (ref.refersTo(null)) {
127
            fail("expected " + which + " to not be cleared");
128
        }
129
    }
130

131
    private static void expectValue(Reference<TestObject> ref,
132
                                    TestObject value,
133
                                    String which) throws Exception {
134
        expectNotValue(ref, testObjectNone, which);
135
        expectNotCleared(ref, which);
136
        if (!ref.refersTo(value)) {
137
            fail(which + " doesn't refer to expected value");
138
        }
139
    }
140

141
    private static void expectNotValue(Reference<TestObject> ref,
142
                                       TestObject value,
143
                                       String which) throws Exception {
144
        if (ref.refersTo(value)) {
145
            fail(which + " refers to unexpected value");
146
        }
147
    }
148

149
    private static void checkInitialStates() throws Exception {
150
        expectValue(testPhantom1, testObject1, "testPhantom1");
151
        expectValue(testWeak2, testObject2, "testWeak2");
152
        expectValue(testWeak3, testObject3, "testWeak3");
153
        expectValue(testWeak4, testObject4, "testWeak4");
154
    }
155

156
    private static void discardStrongReferences() {
157
        // testObjectNone not dropped
158
        testObject1 = null;
159
        testObject2 = null;
160
        // testObject3 not dropped
161
        testObject4 = null;
162
    }
163

164
    private static void testConcurrentCollection() throws Exception {
165
        progress("setup concurrent collection test");
166
        setup();
167
        progress("gcUntilOld");
168
        gcUntilOld();
169

170
        progress("acquire control of concurrent cycles");
171
        WB.concurrentGCAcquireControl();
172
        try {
173
            progress("check initial states");
174
            checkInitialStates();
175

176
            progress("discard strong references");
177
            discardStrongReferences();
178

179
            progress("run GC to before marking completed");
180
            WB.concurrentGCRunTo(WB.BEFORE_MARKING_COMPLETED);
181

182
            progress("fetch test objects, possibly keeping some alive");
183
            expectNotCleared(testPhantom1, "testPhantom1");
184
            expectNotCleared(testWeak2, "testWeak2");
185
            expectValue(testWeak3, testObject3, "testWeak3");
186

187
            // For some collectors, calling get() will keep testObject4 alive.
188
            if (testWeak4.get() == null) {
189
                fail("testWeak4 unexpectedly == null");
190
            }
191

192
            progress("finish collection");
193
            WB.concurrentGCRunToIdle();
194

195
            progress("verify expected clears");
196
            expectCleared(testPhantom1, "testPhantom1");
197
            expectCleared(testWeak2, "testWeak2");
198
            expectValue(testWeak3, testObject3, "testWeak3");
199

200
            progress("verify get returns expected values");
201
            if (testWeak2.get() != null) {
202
                fail("testWeak2.get() != null");
203
            }
204

205
            TestObject obj3 = testWeak3.get();
206
            if (obj3 == null) {
207
                fail("testWeak3.get() returned null");
208
            } else if (obj3.value != 3) {
209
                fail("testWeak3.get().value is " + obj3.value);
210
            }
211

212
            TestObject obj4 = testWeak4.get();
213

214
            progress("verify queue entries");
215
            long timeout = 60000; // 1 minute of milliseconds.
216
            while (true) {
217
                Reference<? extends TestObject> ref = queue.remove(timeout);
218
                if (ref == null) {
219
                    break;
220
                } else if (ref == testPhantom1) {
221
                    testPhantom1 = null;
222
                } else if (ref == testWeak2) {
223
                    testWeak2 = null;
224
                } else if (ref == testWeak3) {
225
                    testWeak3 = null;
226
                } else if (ref == testWeak4) {
227
                    testWeak4 = null;
228
                } else {
229
                    fail("unexpected reference in queue");
230
                }
231
            }
232
            if (testPhantom1 != null) {
233
                fail("testPhantom1 not notified");
234
            } else if (testWeak2 != null) {
235
                fail("testWeak2 not notified");
236
            } else if (testWeak3 == null) {
237
                fail("testWeak3 notified");
238
            }
239
            if ((testWeak4 == null) != (obj4 == null)) {
240
                fail("either referent is cleared and we got notified, or neither of this happened: referent: "
241
                     + obj4 + ", notified: " + (testWeak4 == null));
242
            }
243

244
        } finally {
245
            progress("release control of concurrent cycles");
246
            WB.concurrentGCReleaseControl();
247
        }
248
        progress("finished concurrent collection test");
249
    }
250

251
    private static void testSimpleCollection() throws Exception {
252
        progress("setup simple collection test");
253
        setup();
254
        progress("gcUntilOld");
255
        gcUntilOld();
256

257
        progress("check initial states");
258
        checkInitialStates();
259

260
        progress("discard strong references");
261
        TestObject tw4 = testWeak4.get(); // Keep testObject4 alive.
262
        discardStrongReferences();
263

264
        progress("collect garbage");
265
        WB.fullGC();
266

267
        progress("verify expected clears");
268
        expectCleared(testPhantom1, "testPhantom1");
269
        expectCleared(testWeak2, "testWeak2");
270
        expectValue(testWeak3, testObject3, "testWeak3");
271
        expectNotCleared(testWeak4, "testWeak4");
272

273
        progress("verify get returns expected values");
274
        if (testWeak2.get() != null) {
275
            fail("testWeak2.get() != null");
276
        } else if (testWeak3.get() != testObject3) {
277
            fail("testWeak3.get() is not expected value");
278
        } else if (testWeak4.get() != tw4) {
279
            fail("testWeak4.get() is not expected value");
280
        }
281

282
        progress("finished simple collection test");
283
    }
284

285
    public static void main(String[] args) throws Exception {
286
        if (WB.supportsConcurrentGCBreakpoints()) {
287
            testConcurrentCollection();
288
        }
289
        testSimpleCollection();
290
    }
291
}
292

Использование cookies

Мы используем файлы cookie в соответствии с Политикой конфиденциальности и Политикой использования cookies.

Нажимая кнопку «Принимаю», Вы даете АО «СберТех» согласие на обработку Ваших персональных данных в целях совершенствования нашего веб-сайта и Сервиса GitVerse, а также повышения удобства их использования.

Запретить использование cookies Вы можете самостоятельно в настройках Вашего браузера.