blob: 8c7c27d79c3267da466716bc637688d9e009eea2 [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
71 public static void main(String[] args) {
Brian Carlstromc8494452014-02-20 13:50:05 -080072 WeakReference<FinalizerTest> wimp = makeRef();
Mathieu Chartieref9849e2015-06-27 15:42:27 -070073 FinalizerTest keepLive = wimp.get();
jeffhao5d1ac922011-09-29 17:41:15 -070074
75 System.out.println("wimp: " + wimpString(wimp));
76
77 /* this will try to collect and finalize ft */
Mathieu Chartieref9849e2015-06-27 15:42:27 -070078 keepLive = null;
jeffhao5d1ac922011-09-29 17:41:15 -070079 System.out.println("gc");
Mathieu Chartier7befd0e2014-02-03 17:48:41 -080080 Runtime.getRuntime().gc();
jeffhao5d1ac922011-09-29 17:41:15 -070081
82 System.out.println("wimp: " + wimpString(wimp));
83 System.out.println("finalize");
84 System.runFinalization();
85 System.out.println("wimp: " + wimpString(wimp));
86
87 System.out.println("sleep");
88 snooze(1000);
89
90 System.out.println("reborn: " + FinalizerTest.mReborn);
91 System.out.println("wimp: " + wimpString(wimp));
92 System.out.println("reset reborn");
Mathieu Chartier7befd0e2014-02-03 17:48:41 -080093 Runtime.getRuntime().gc();
jeffhao5d1ac922011-09-29 17:41:15 -070094 FinalizerTest.mReborn = FinalizerTest.mNothing;
95 System.out.println("gc + finalize");
96 System.gc();
97 System.runFinalization();
98
99 System.out.println("sleep");
100 snooze(1000);
101
102 System.out.println("reborn: " + FinalizerTest.mReborn);
103 System.out.println("wimp: " + wimpString(wimp));
Mathieu Chartier3a5fa5e2014-09-04 14:15:35 -0700104 // Test runFinalization with multiple objects.
105 runFinalizationTest();
106 }
107
108 static class FinalizeCounter {
Mathieu Chartierbbb54792014-10-15 09:59:03 -0700109 public static final int maxCount = 1024;
110 public static boolean finalized[] = new boolean[maxCount];
Mathieu Chartier3a5fa5e2014-09-04 14:15:35 -0700111 private static Object finalizeLock = new Object();
112 private static volatile int finalizeCount = 0;
113 private int index;
114 static int getCount() {
115 return finalizeCount;
116 }
Mathieu Chartierbbb54792014-10-15 09:59:03 -0700117 static void printNonFinalized() {
118 for (int i = 0; i < maxCount; ++i) {
119 if (!FinalizeCounter.finalized[i]) {
120 System.err.println("Element " + i + " was not finalized");
121 }
122 }
123 }
Mathieu Chartier3a5fa5e2014-09-04 14:15:35 -0700124 FinalizeCounter(int index) {
125 this.index = index;
126 }
127 protected void finalize() {
128 synchronized(finalizeLock) {
129 ++finalizeCount;
Mathieu Chartierbbb54792014-10-15 09:59:03 -0700130 finalized[index] = true;
Mathieu Chartier3a5fa5e2014-09-04 14:15:35 -0700131 }
132 }
133 }
134
Mathieu Chartier8cb03062014-10-13 10:58:01 -0700135 private static void allocFinalizableObjects(int count) {
Mathieu Chartier3a5fa5e2014-09-04 14:15:35 -0700136 Object[] objs = new Object[count];
137 for (int i = 0; i < count; ++i) {
138 objs[i] = new FinalizeCounter(i);
139 }
Mathieu Chartier8cb03062014-10-13 10:58:01 -0700140 }
141
142 private static void runFinalizationTest() {
Mathieu Chartierbbb54792014-10-15 09:59:03 -0700143 allocFinalizableObjects(FinalizeCounter.maxCount);
Mathieu Chartier8cb03062014-10-13 10:58:01 -0700144 Runtime.getRuntime().gc();
Mathieu Chartier3a5fa5e2014-09-04 14:15:35 -0700145 System.runFinalization();
Mathieu Chartierbbb54792014-10-15 09:59:03 -0700146 System.out.println("Finalized " + FinalizeCounter.getCount() + " / " + FinalizeCounter.maxCount);
147 if (FinalizeCounter.getCount() != FinalizeCounter.maxCount) {
148 // Print out all the finalized elements.
149 FinalizeCounter.printNonFinalized();
150 // Try to sleep for a couple seconds to see if the objects became finalized after.
151 try {
152 java.lang.Thread.sleep(2000);
153 } catch (InterruptedException e) {
154 }
155 System.out.println("After sleep finalized " + FinalizeCounter.getCount() + " / " + FinalizeCounter.maxCount);
156 FinalizeCounter.printNonFinalized();
157 }
jeffhao5d1ac922011-09-29 17:41:15 -0700158 }
Brian Carlstromc8494452014-02-20 13:50:05 -0800159
160 public static class FinalizerTest {
161 public static FinalizerTest mNothing = new FinalizerTest("nothing");
162 public static FinalizerTest mReborn = mNothing;
163
164 private final String message;
165 private boolean finalized = false;
166
167 public FinalizerTest(String message) {
168 this.message = message;
169 }
170
171 public String toString() {
172 return "[FinalizerTest message=" + message +
173 ", finalized=" + finalized + "]";
174 }
175
176 protected void finalize() {
177 finalized = true;
178 mReborn = this;
179 }
180 }
jeffhao5d1ac922011-09-29 17:41:15 -0700181}