blob: 0de56f9a7c5cabff2768fe22249f2813812cabdf [file] [log] [blame]
Elliott Hughes2faa5f12012-01-30 14:42:07 -08001/*
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 */
jeffhao5d1ac922011-09-29 17:41:15 -070016
17import java.lang.ref.WeakReference;
Brian Carlstromc8494452014-02-20 13:50:05 -080018import java.util.ArrayList;
19import java.util.List;
jeffhao5d1ac922011-09-29 17:41:15 -070020
21/**
22 * Some finalizer tests.
23 *
24 * This only works if System.runFinalization() causes finalizers to run
25 * immediately or very soon.
26 */
27public class Main {
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
Brian Carlstromc8494452014-02-20 13:50:05 -080036 public static WeakReference<FinalizerTest> makeRef() {
Mathieu Chartieref9849e2015-06-27 15:42:27 -070037 FinalizerTest ft = new FinalizerTest("wahoo");
38 WeakReference<FinalizerTest> ref = new WeakReference<FinalizerTest>(ft);
39 ft = null;
40 return ref;
jeffhao5d1ac922011-09-29 17:41:15 -070041 }
42
Brian Carlstromc8494452014-02-20 13:50:05 -080043 public static String wimpString(final WeakReference<FinalizerTest> wimp) {
jeffhao5d1ac922011-09-29 17:41:15 -070044 /*
45 * Do the work in another thread, so there is no danger of a
46 * conservative reference to ft leaking onto the main thread's
47 * stack.
48 */
49
50 final String[] s = new String[1];
51 Thread t = new Thread() {
52 public void run() {
Brian Carlstromc8494452014-02-20 13:50:05 -080053 FinalizerTest ref = wimp.get();
jeffhao5d1ac922011-09-29 17:41:15 -070054 if (ref != null) {
55 s[0] = ref.toString();
56 }
57 }
58 };
59
60 t.start();
61
62 try {
63 t.join();
64 } catch (InterruptedException ie) {
65 throw new RuntimeException(ie);
66 }
67
68 return s[0];
69 }
70
Sebastien Hertz19ac0272015-02-24 17:39:50 +010071 private static void printWeakReference(WeakReference<FinalizerTest> wimp) {
72 // Reference ft so we are sure the WeakReference cannot be cleared.
73 FinalizerTest keepLive = wimp.get();
74 System.out.println("wimp: " + wimpString(wimp));
75 }
76
jeffhao5d1ac922011-09-29 17:41:15 -070077 public static void main(String[] args) {
Brian Carlstromc8494452014-02-20 13:50:05 -080078 WeakReference<FinalizerTest> wimp = makeRef();
Sebastien Hertz19ac0272015-02-24 17:39:50 +010079 printWeakReference(wimp);
jeffhao5d1ac922011-09-29 17:41:15 -070080
81 /* this will try to collect and finalize ft */
82 System.out.println("gc");
Mathieu Chartier7befd0e2014-02-03 17:48:41 -080083 Runtime.getRuntime().gc();
jeffhao5d1ac922011-09-29 17:41:15 -070084
85 System.out.println("wimp: " + wimpString(wimp));
86 System.out.println("finalize");
87 System.runFinalization();
88 System.out.println("wimp: " + wimpString(wimp));
89
90 System.out.println("sleep");
91 snooze(1000);
92
93 System.out.println("reborn: " + FinalizerTest.mReborn);
94 System.out.println("wimp: " + wimpString(wimp));
95 System.out.println("reset reborn");
Mathieu Chartier7befd0e2014-02-03 17:48:41 -080096 Runtime.getRuntime().gc();
jeffhao5d1ac922011-09-29 17:41:15 -070097 FinalizerTest.mReborn = FinalizerTest.mNothing;
98 System.out.println("gc + finalize");
99 System.gc();
100 System.runFinalization();
101
102 System.out.println("sleep");
103 snooze(1000);
104
105 System.out.println("reborn: " + FinalizerTest.mReborn);
106 System.out.println("wimp: " + wimpString(wimp));
Mathieu Chartier3a5fa5e2014-09-04 14:15:35 -0700107 // Test runFinalization with multiple objects.
108 runFinalizationTest();
109 }
110
111 static class FinalizeCounter {
Mathieu Chartierbbb54792014-10-15 09:59:03 -0700112 public static final int maxCount = 1024;
113 public static boolean finalized[] = new boolean[maxCount];
Mathieu Chartier3a5fa5e2014-09-04 14:15:35 -0700114 private static Object finalizeLock = new Object();
115 private static volatile int finalizeCount = 0;
116 private int index;
117 static int getCount() {
118 return finalizeCount;
119 }
Mathieu Chartierbbb54792014-10-15 09:59:03 -0700120 static void printNonFinalized() {
121 for (int i = 0; i < maxCount; ++i) {
122 if (!FinalizeCounter.finalized[i]) {
123 System.err.println("Element " + i + " was not finalized");
124 }
125 }
126 }
Mathieu Chartier3a5fa5e2014-09-04 14:15:35 -0700127 FinalizeCounter(int index) {
128 this.index = index;
129 }
130 protected void finalize() {
131 synchronized(finalizeLock) {
132 ++finalizeCount;
Mathieu Chartierbbb54792014-10-15 09:59:03 -0700133 finalized[index] = true;
Mathieu Chartier3a5fa5e2014-09-04 14:15:35 -0700134 }
135 }
136 }
137
Mathieu Chartier8cb03062014-10-13 10:58:01 -0700138 private static void allocFinalizableObjects(int count) {
Mathieu Chartier3a5fa5e2014-09-04 14:15:35 -0700139 Object[] objs = new Object[count];
140 for (int i = 0; i < count; ++i) {
141 objs[i] = new FinalizeCounter(i);
142 }
Mathieu Chartier8cb03062014-10-13 10:58:01 -0700143 }
144
145 private static void runFinalizationTest() {
Mathieu Chartierbbb54792014-10-15 09:59:03 -0700146 allocFinalizableObjects(FinalizeCounter.maxCount);
Mathieu Chartier8cb03062014-10-13 10:58:01 -0700147 Runtime.getRuntime().gc();
Mathieu Chartier3a5fa5e2014-09-04 14:15:35 -0700148 System.runFinalization();
Mathieu Chartierbbb54792014-10-15 09:59:03 -0700149 System.out.println("Finalized " + FinalizeCounter.getCount() + " / " + FinalizeCounter.maxCount);
150 if (FinalizeCounter.getCount() != FinalizeCounter.maxCount) {
151 // Print out all the finalized elements.
152 FinalizeCounter.printNonFinalized();
153 // Try to sleep for a couple seconds to see if the objects became finalized after.
154 try {
155 java.lang.Thread.sleep(2000);
156 } catch (InterruptedException e) {
157 }
158 System.out.println("After sleep finalized " + FinalizeCounter.getCount() + " / " + FinalizeCounter.maxCount);
159 FinalizeCounter.printNonFinalized();
160 }
jeffhao5d1ac922011-09-29 17:41:15 -0700161 }
Brian Carlstromc8494452014-02-20 13:50:05 -0800162
163 public static class FinalizerTest {
164 public static FinalizerTest mNothing = new FinalizerTest("nothing");
165 public static FinalizerTest mReborn = mNothing;
166
167 private final String message;
168 private boolean finalized = false;
169
170 public FinalizerTest(String message) {
171 this.message = message;
172 }
173
174 public String toString() {
175 return "[FinalizerTest message=" + message +
176 ", finalized=" + finalized + "]";
177 }
178
179 protected void finalize() {
180 finalized = true;
181 mReborn = this;
182 }
183 }
jeffhao5d1ac922011-09-29 17:41:15 -0700184}