/* * Copyright (C) 2009 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ import java.lang.ref.WeakReference; public class Main { public static void main(String[] args) { staleStackTest(); } public static void staleStackTest() { WeakReference wrefs[] = new WeakReference[10]; populate(wrefs); check(wrefs); } static void populate(WeakReference[] wrefs) { /* * Get a bunch of non-constant String objects into registers. These * should be the first locals declared. */ String str0 = generateString("String", 0); String str1 = generateString("String", 1); String str2 = generateString("String", 2); String str3 = generateString("String", 3); String str4 = generateString("String", 4); String str5 = generateString("String", 5); String str6 = generateString("String", 6); String str7 = generateString("String", 7); String str8 = generateString("String", 8); String str9 = generateString("String", 9); /* stuff them into the weak references array */ wrefs[0] = new WeakReference(str0); wrefs[1] = new WeakReference(str1); wrefs[2] = new WeakReference(str2); wrefs[3] = new WeakReference(str3); wrefs[4] = new WeakReference(str4); wrefs[5] = new WeakReference(str5); wrefs[6] = new WeakReference(str6); wrefs[7] = new WeakReference(str7); wrefs[8] = new WeakReference(str8); wrefs[9] = new WeakReference(str9); } static String generateString(String base, int num) { return base + num; } static void check(WeakReference[] wrefs) { /* * Declare locals so that our stack overlaps the same region * that populate() did. */ String str0; String str1; String str2; String str3; String str4; String str5; String str6; String str7; String str8; String str9; int numValid = 0; /* * This *should* blow out all the weakly-reference objects. If * we still have stale copies of references on the stack, a * conservative GC will try to hold on to those objects and the * count will be nonzero. * * Getting a zero result here isn't conclusive, but it's a strong * indicator that precise GC is having an impact. */ Runtime.getRuntime().gc(); for (int i = 0; i < wrefs.length; i++) { if (wrefs[i].get() != null) numValid++; } System.out.println("Valid refs: " + numValid); /* use the locals in case the compiler gets smart */ str0 = generateString("String", 0); str1 = generateString("String", 1); str2 = generateString("String", 2); str3 = generateString("String", 3); str4 = generateString("String", 4); str5 = generateString("String", 5); str6 = generateString("String", 6); str7 = generateString("String", 7); str8 = generateString("String", 8); str9 = generateString("String", 9); System.out.println(str0+str1+str2+str3+str4+str5+str6+str7+str8+str9); } }