1 /*
2  * Copyright (C) 2009 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 
19 public class Main {
main(String[] args)20     public static void main(String[] args) {
21         staleStackTest();
22     }
23 
staleStackTest()24     public static void staleStackTest() {
25         WeakReference wrefs[] = new WeakReference[10];
26 
27         populate(wrefs);
28 
29         check(wrefs);
30     }
31 
populate(WeakReference[] wrefs)32     static void populate(WeakReference[] wrefs) {
33         /*
34          * Get a bunch of non-constant String objects into registers.  These
35          * should be the first locals declared.
36          */
37         String str0 = generateString("String", 0);
38         String str1 = generateString("String", 1);
39         String str2 = generateString("String", 2);
40         String str3 = generateString("String", 3);
41         String str4 = generateString("String", 4);
42         String str5 = generateString("String", 5);
43         String str6 = generateString("String", 6);
44         String str7 = generateString("String", 7);
45         String str8 = generateString("String", 8);
46         String str9 = generateString("String", 9);
47 
48         /* stuff them into the weak references array */
49         wrefs[0] = new WeakReference(str0);
50         wrefs[1] = new WeakReference(str1);
51         wrefs[2] = new WeakReference(str2);
52         wrefs[3] = new WeakReference(str3);
53         wrefs[4] = new WeakReference(str4);
54         wrefs[5] = new WeakReference(str5);
55         wrefs[6] = new WeakReference(str6);
56         wrefs[7] = new WeakReference(str7);
57         wrefs[8] = new WeakReference(str8);
58         wrefs[9] = new WeakReference(str9);
59     }
60 
generateString(String base, int num)61     static String generateString(String base, int num) {
62         return base + num;
63     }
64 
check(WeakReference[] wrefs)65     static void check(WeakReference[] wrefs) {
66         /*
67          * Declare locals so that our stack overlaps the same region
68          * that populate() did.
69          */
70         String str0;
71         String str1;
72         String str2;
73         String str3;
74         String str4;
75         String str5;
76         String str6;
77         String str7;
78         String str8;
79         String str9;
80         int numValid = 0;
81 
82         /*
83          * This *should* blow out all the weakly-reference objects.  If
84          * we still have stale copies of references on the stack, a
85          * conservative GC will try to hold on to those objects and the
86          * count will be nonzero.
87          *
88          * Getting a zero result here isn't conclusive, but it's a strong
89          * indicator that precise GC is having an impact.
90          */
91         Runtime.getRuntime().gc();
92 
93         for (int i = 0; i < wrefs.length; i++) {
94             if (wrefs[i].get() != null)
95                 numValid++;
96         }
97 
98         System.out.println("Valid refs: " + numValid);
99 
100         /* use the locals in case the compiler gets smart */
101         str0 = generateString("String", 0);
102         str1 = generateString("String", 1);
103         str2 = generateString("String", 2);
104         str3 = generateString("String", 3);
105         str4 = generateString("String", 4);
106         str5 = generateString("String", 5);
107         str6 = generateString("String", 6);
108         str7 = generateString("String", 7);
109         str8 = generateString("String", 8);
110         str9 = generateString("String", 9);
111         System.out.println(str0+str1+str2+str3+str4+str5+str6+str7+str8+str9);
112     }
113 }
114