blob: 390472df4f2afad1672155d9443d3404cf12eac5 [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() {
jeffhao5d1ac922011-09-29 17:41:15 -070037 /*
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
Brian Carlstromc8494452014-02-20 13:50:05 -080043 final List<WeakReference<FinalizerTest>> wimp =
44 new ArrayList<WeakReference<FinalizerTest>>();
jeffhao5d1ac922011-09-29 17:41:15 -070045 Thread t = new Thread() {
46 public void run() {
47 FinalizerTest ft = new FinalizerTest("wahoo");
Brian Carlstromc8494452014-02-20 13:50:05 -080048 wimp.add(new WeakReference<FinalizerTest>(ft));
jeffhao5d1ac922011-09-29 17:41:15 -070049 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
Brian Carlstromc8494452014-02-20 13:50:05 -080061 return wimp.get(0);
jeffhao5d1ac922011-09-29 17:41:15 -070062 }
63
Brian Carlstromc8494452014-02-20 13:50:05 -080064 public static String wimpString(final WeakReference<FinalizerTest> wimp) {
jeffhao5d1ac922011-09-29 17:41:15 -070065 /*
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() {
Brian Carlstromc8494452014-02-20 13:50:05 -080074 FinalizerTest ref = wimp.get();
jeffhao5d1ac922011-09-29 17:41:15 -070075 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
92 public static void main(String[] args) {
Brian Carlstromc8494452014-02-20 13:50:05 -080093 WeakReference<FinalizerTest> wimp = makeRef();
jeffhao5d1ac922011-09-29 17:41:15 -070094
95 System.out.println("wimp: " + wimpString(wimp));
96
97 /* this will try to collect and finalize ft */
98 System.out.println("gc");
Mathieu Chartier7befd0e2014-02-03 17:48:41 -080099 Runtime.getRuntime().gc();
jeffhao5d1ac922011-09-29 17:41:15 -0700100
101 System.out.println("wimp: " + wimpString(wimp));
102 System.out.println("finalize");
103 System.runFinalization();
104 System.out.println("wimp: " + wimpString(wimp));
105
106 System.out.println("sleep");
107 snooze(1000);
108
109 System.out.println("reborn: " + FinalizerTest.mReborn);
110 System.out.println("wimp: " + wimpString(wimp));
111 System.out.println("reset reborn");
Mathieu Chartier7befd0e2014-02-03 17:48:41 -0800112 Runtime.getRuntime().gc();
jeffhao5d1ac922011-09-29 17:41:15 -0700113 FinalizerTest.mReborn = FinalizerTest.mNothing;
114 System.out.println("gc + finalize");
115 System.gc();
116 System.runFinalization();
117
118 System.out.println("sleep");
119 snooze(1000);
120
121 System.out.println("reborn: " + FinalizerTest.mReborn);
122 System.out.println("wimp: " + wimpString(wimp));
Mathieu Chartier3a5fa5e2014-09-04 14:15:35 -0700123 // Test runFinalization with multiple objects.
124 runFinalizationTest();
125 }
126
127 static class FinalizeCounter {
128 private static Object finalizeLock = new Object();
129 private static volatile int finalizeCount = 0;
130 private int index;
131 static int getCount() {
132 return finalizeCount;
133 }
134 FinalizeCounter(int index) {
135 this.index = index;
136 }
137 protected void finalize() {
138 synchronized(finalizeLock) {
139 ++finalizeCount;
140 }
141 }
142 }
143
144 private static void runFinalizationTest() {
145 int count = 1024;
146 Object[] objs = new Object[count];
147 for (int i = 0; i < count; ++i) {
148 objs[i] = new FinalizeCounter(i);
149 }
150 for (int i = 0; i < count; ++i) {
151 objs[i] = null;
152 }
153 System.gc();
154 System.runFinalization();
155 System.out.println("Finalized " + FinalizeCounter.getCount() + " / " + count);
jeffhao5d1ac922011-09-29 17:41:15 -0700156 }
Brian Carlstromc8494452014-02-20 13:50:05 -0800157
158 public static class FinalizerTest {
159 public static FinalizerTest mNothing = new FinalizerTest("nothing");
160 public static FinalizerTest mReborn = mNothing;
161
162 private final String message;
163 private boolean finalized = false;
164
165 public FinalizerTest(String message) {
166 this.message = message;
167 }
168
169 public String toString() {
170 return "[FinalizerTest message=" + message +
171 ", finalized=" + finalized + "]";
172 }
173
174 protected void finalize() {
175 finalized = true;
176 mReborn = this;
177 }
178 }
jeffhao5d1ac922011-09-29 17:41:15 -0700179}