Home | History | Annotate | Download | only in src
      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 {
     20     public static void main(String[] args) {
     21         staleStackTest();
     22     }
     23 
     24     public static void staleStackTest() {
     25         WeakReference wrefs[] = new WeakReference[10];
     26 
     27         populate(wrefs);
     28 
     29         check(wrefs);
     30     }
     31 
     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 
     61     static String generateString(String base, int num) {
     62         return base + num;
     63     }
     64 
     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         System.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