1 /* 2 * Copyright (C) 2008 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 import java.lang.ref.WeakReference; 18 import java.util.ArrayList; 19 import java.util.List; 20 21 /** 22 * Some finalizer tests. 23 * 24 * This only works if System.runFinalization() causes finalizers to run 25 * immediately or very soon. 26 */ 27 public class Main { snooze(int ms)28 private static void snooze(int ms) { 29 try { 30 Thread.sleep(ms); 31 } catch (InterruptedException ie) { 32 System.out.println("Snooze: " + ie.getMessage()); 33 } 34 } 35 makeRef()36 public static WeakReference<FinalizerTest> makeRef() { 37 /* 38 * Make ft in another thread, so there is no danger of 39 * a conservative reference leaking onto the main thread's 40 * stack. 41 */ 42 43 final List<WeakReference<FinalizerTest>> wimp = 44 new ArrayList<WeakReference<FinalizerTest>>(); 45 Thread t = new Thread() { 46 public void run() { 47 FinalizerTest ft = new FinalizerTest("wahoo"); 48 wimp.add(new WeakReference<FinalizerTest>(ft)); 49 ft = null; 50 } 51 }; 52 53 t.start(); 54 55 try { 56 t.join(); 57 } catch (InterruptedException ie) { 58 throw new RuntimeException(ie); 59 } 60 61 return wimp.get(0); 62 } 63 wimpString(final WeakReference<FinalizerTest> wimp)64 public static String wimpString(final WeakReference<FinalizerTest> wimp) { 65 /* 66 * Do the work in another thread, so there is no danger of a 67 * conservative reference to ft leaking onto the main thread's 68 * stack. 69 */ 70 71 final String[] s = new String[1]; 72 Thread t = new Thread() { 73 public void run() { 74 FinalizerTest ref = wimp.get(); 75 if (ref != null) { 76 s[0] = ref.toString(); 77 } 78 } 79 }; 80 81 t.start(); 82 83 try { 84 t.join(); 85 } catch (InterruptedException ie) { 86 throw new RuntimeException(ie); 87 } 88 89 return s[0]; 90 } 91 printWeakReference(WeakReference<FinalizerTest> wimp)92 private static void printWeakReference(WeakReference<FinalizerTest> wimp) { 93 // Reference ft so we are sure the WeakReference cannot be cleared. 94 FinalizerTest keepLive = wimp.get(); 95 System.out.println("wimp: " + wimpString(wimp)); 96 } 97 main(String[] args)98 public static void main(String[] args) { 99 WeakReference<FinalizerTest> wimp = makeRef(); 100 printWeakReference(wimp); 101 102 /* this will try to collect and finalize ft */ 103 System.out.println("gc"); 104 Runtime.getRuntime().gc(); 105 106 System.out.println("wimp: " + wimpString(wimp)); 107 System.out.println("finalize"); 108 System.runFinalization(); 109 System.out.println("wimp: " + wimpString(wimp)); 110 111 System.out.println("sleep"); 112 snooze(1000); 113 114 System.out.println("reborn: " + FinalizerTest.mReborn); 115 System.out.println("wimp: " + wimpString(wimp)); 116 System.out.println("reset reborn"); 117 Runtime.getRuntime().gc(); 118 FinalizerTest.mReborn = FinalizerTest.mNothing; 119 System.out.println("gc + finalize"); 120 System.gc(); 121 System.runFinalization(); 122 123 System.out.println("sleep"); 124 snooze(1000); 125 126 System.out.println("reborn: " + FinalizerTest.mReborn); 127 System.out.println("wimp: " + wimpString(wimp)); 128 // Test runFinalization with multiple objects. 129 runFinalizationTest(); 130 } 131 132 static class FinalizeCounter { 133 public static final int maxCount = 1024; 134 public static boolean finalized[] = new boolean[maxCount]; 135 private static Object finalizeLock = new Object(); 136 private static volatile int finalizeCount = 0; 137 private int index; getCount()138 static int getCount() { 139 return finalizeCount; 140 } printNonFinalized()141 static void printNonFinalized() { 142 for (int i = 0; i < maxCount; ++i) { 143 if (!FinalizeCounter.finalized[i]) { 144 System.err.println("Element " + i + " was not finalized"); 145 } 146 } 147 } FinalizeCounter(int index)148 FinalizeCounter(int index) { 149 this.index = index; 150 } finalize()151 protected void finalize() { 152 synchronized(finalizeLock) { 153 ++finalizeCount; 154 finalized[index] = true; 155 } 156 } 157 } 158 allocFinalizableObjects(int count)159 private static void allocFinalizableObjects(int count) { 160 Object[] objs = new Object[count]; 161 for (int i = 0; i < count; ++i) { 162 objs[i] = new FinalizeCounter(i); 163 } 164 } 165 runFinalizationTest()166 private static void runFinalizationTest() { 167 allocFinalizableObjects(FinalizeCounter.maxCount); 168 Runtime.getRuntime().gc(); 169 System.runFinalization(); 170 System.out.println("Finalized " + FinalizeCounter.getCount() + " / " + FinalizeCounter.maxCount); 171 if (FinalizeCounter.getCount() != FinalizeCounter.maxCount) { 172 // Print out all the finalized elements. 173 FinalizeCounter.printNonFinalized(); 174 // Try to sleep for a couple seconds to see if the objects became finalized after. 175 try { 176 java.lang.Thread.sleep(2000); 177 } catch (InterruptedException e) { 178 } 179 System.out.println("After sleep finalized " + FinalizeCounter.getCount() + " / " + FinalizeCounter.maxCount); 180 FinalizeCounter.printNonFinalized(); 181 } 182 } 183 184 public static class FinalizerTest { 185 public static FinalizerTest mNothing = new FinalizerTest("nothing"); 186 public static FinalizerTest mReborn = mNothing; 187 188 private final String message; 189 private boolean finalized = false; 190 FinalizerTest(String message)191 public FinalizerTest(String message) { 192 this.message = message; 193 } 194 toString()195 public String toString() { 196 return "[FinalizerTest message=" + message + 197 ", finalized=" + finalized + "]"; 198 } 199 finalize()200 protected void finalize() { 201 finalized = true; 202 mReborn = this; 203 } 204 } 205 } 206