1 /* 2 * Copyright (c) 1997, 2012, 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 /* @test 25 * @summary Basic functional test of reference objects 26 * @author Mark Reinhold 27 */ 28 package test.java.lang.ref; 29 30 import java.lang.ref.*; 31 import java.util.Vector; 32 33 import org.testng.annotations.Test; 34 35 public class BasicTest { 36 37 static ReferenceQueue q = new ReferenceQueue(); 38 static ReferenceQueue q2 = new ReferenceQueue(); 39 static Reference rw, rw2, rp, rp2; 40 static Vector keep = new Vector(); 41 static boolean finalized = false; 42 43 public static class ClearFinalizerThread { finalize()44 protected void finalize() { 45 System.err.println("Cleared finalizer thread"); 46 } 47 }; 48 finalize()49 protected void finalize() { 50 BasicTest.finalized = true; 51 System.err.println("Finalized " + this); 52 } 53 54 public static class Sub { }; 55 56 Object sub = new Sub(); 57 fork(Runnable proc)58 static void fork(Runnable proc) throws InterruptedException { 59 Thread t = new Thread(proc); 60 t.start(); 61 t.join(); 62 } 63 showReferences()64 static void showReferences() throws InterruptedException { 65 fork(new Runnable() { 66 public void run() { 67 System.err.println("References: W " + rw.get() 68 + ", W2 " + rw2.get() 69 + ", P " + rp.get() 70 + ", P2 " + rp2.get()); 71 } 72 }); 73 } 74 createNoise()75 static void createNoise() throws InterruptedException { 76 fork(new Runnable() { 77 public void run() { 78 keep.addElement(new PhantomReference(new Object(), q2)); 79 } 80 }); 81 } 82 83 @Test test()84 public void test() throws Exception { 85 86 fork(new Runnable() { 87 public void run() { 88 BasicTest s = new BasicTest(); 89 rw = new WeakReference(s, q); 90 rw2 = new WeakReference(s); 91 rp = new PhantomReference(s, q); 92 rp2 = new PhantomReference(s.sub, q); 93 s = null; 94 } 95 }); 96 97 showReferences(); 98 99 int ndq = 0; 100 boolean prevFinalized = false; 101 outer: 102 for (int i = 1;; i++) { 103 Reference r; 104 105 createNoise(); 106 System.err.println("GC " + i); 107 Thread.sleep(10); 108 System.gc(); 109 System.runFinalization(); 110 111 showReferences(); 112 while ((r = q2.poll()) != null) { 113 System.err.println("Noise " + r); 114 } 115 116 /* Cause a dummy object to be finalized, since the finalizer thread 117 might retain a reference to the Basic instance after it's been 118 finalized (this happens with java_g) */ 119 if (BasicTest.finalized && !prevFinalized) { 120 fork(new Runnable() { 121 public void run() { 122 new ClearFinalizerThread(); 123 }}); 124 prevFinalized = true; 125 } 126 127 while ((r = q.poll()) != null) { 128 ndq++; 129 if (r != null) { 130 System.err.println("Dequeued " + r); 131 if (ndq == 3) break outer; 132 } 133 } 134 135 if (i >= 10) break; 136 137 } 138 139 if (ndq != 3) { 140 throw new Exception("Expected to dequeue 3 reference objects," 141 + " but only got " + ndq); 142 } 143 144 if (! BasicTest.finalized) { 145 throw new Exception("Test object not finalized"); 146 } 147 148 } 149 150 } 151