15d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao/* 25d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * Copyright (C) 2009 The Android Open Source Project 35d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * 45d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * Licensed under the Apache License, Version 2.0 (the "License"); 55d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * you may not use this file except in compliance with the License. 65d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * You may obtain a copy of the License at 75d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * 85d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * http://www.apache.org/licenses/LICENSE-2.0 95d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * 105d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * Unless required by applicable law or agreed to in writing, software 115d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * distributed under the License is distributed on an "AS IS" BASIS, 125d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 135d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * See the License for the specific language governing permissions and 145d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * limitations under the License. 155d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao */ 165d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao 175d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhaoimport java.io.File; 185d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhaoimport java.lang.ref.WeakReference; 195d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhaoimport java.lang.reflect.Method; 205d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhaoimport java.lang.reflect.InvocationTargetException; 215d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao 225d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhaopublic class Main { 235d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao public static volatile boolean quit = false; 245d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao public static final boolean DEBUG = false; 255d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao 265d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao private static final boolean WRITE_HPROF_DATA = false; 275d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao private static final int TEST_TIME = 10; 285d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao private static final String OUTPUT_FILE = "gc-thrash.hprof"; 295d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao 305d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao public static void main(String[] args) { 315d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao // dump heap before 325d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao 335d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao System.out.println("Running (" + TEST_TIME + " seconds) ..."); 345d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao runTests(); 355d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao 365d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao Method dumpHprofDataMethod = null; 375d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao String dumpFile = null; 385d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao 395d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao if (WRITE_HPROF_DATA) { 405d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao dumpHprofDataMethod = getDumpHprofDataMethod(); 415d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao if (dumpHprofDataMethod != null) { 425d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao dumpFile = getDumpFileName(); 435d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao System.out.println("Sending output to " + dumpFile); 445d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao } 455d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao } 465d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao 475d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao System.gc(); 485d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao System.runFinalization(); 495d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao System.gc(); 505d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao 515d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao if (WRITE_HPROF_DATA && dumpHprofDataMethod != null) { 525d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao try { 535d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao dumpHprofDataMethod.invoke(null, dumpFile); 545d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao } catch (IllegalAccessException iae) { 555d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao System.err.println(iae); 565d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao } catch (InvocationTargetException ite) { 575d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao System.err.println(ite); 585d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao } 595d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao } 605d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao 615d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao System.out.println("Done."); 625d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao } 635d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao 645d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao /** 655d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * Finds VMDebug.dumpHprofData() through reflection. In the reference 665d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * implementation this will not be available. 675d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * 685d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * @return the reflection object, or null if the method can't be found 695d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao */ 705d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao private static Method getDumpHprofDataMethod() { 715d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao ClassLoader myLoader = Main.class.getClassLoader(); 725d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao Class vmdClass; 735d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao try { 745d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao vmdClass = myLoader.loadClass("dalvik.system.VMDebug"); 755d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao } catch (ClassNotFoundException cnfe) { 765d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao return null; 775d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao } 785d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao 795d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao Method meth; 805d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao try { 815d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao meth = vmdClass.getMethod("dumpHprofData", 825d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao new Class[] { String.class }); 835d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao } catch (NoSuchMethodException nsme) { 845d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao System.err.println("Found VMDebug but not dumpHprofData method"); 855d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao return null; 865d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao } 875d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao 885d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao return meth; 895d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao } 905d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao 915d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao private static String getDumpFileName() { 925d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao File tmpDir = new File("/tmp"); 935d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao if (tmpDir.exists() && tmpDir.isDirectory()) { 945d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao return "/tmp/" + OUTPUT_FILE; 955d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao } 965d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao 975d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao File sdcard = new File("/sdcard"); 985d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao if (sdcard.exists() && sdcard.isDirectory()) { 995d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao return "/sdcard/" + OUTPUT_FILE; 1005d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao } 1015d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao 1025d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao return null; 1035d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao } 1045d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao 1055d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao 1065d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao /** 1075d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * Run the various tests for a set period. 1085d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao */ 1095d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao public static void runTests() { 1105d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao Robin robin = new Robin(); 1115d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao Deep deep = new Deep(); 1125d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao Large large = new Large(); 1135d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao 1145d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao /* start all threads */ 1155d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao robin.start(); 1165d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao deep.start(); 1175d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao large.start(); 1185d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao 1195d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao /* let everybody run for 10 seconds */ 1205d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao sleep(TEST_TIME * 1000); 1215d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao 1225d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao quit = true; 1235d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao 1245d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao try { 1255d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao /* wait for all threads to stop */ 1265d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao robin.join(); 1275d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao deep.join(); 1285d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao large.join(); 1295d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao } catch (InterruptedException ie) { 1305d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao System.err.println("join was interrupted"); 1315d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao } 1325d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao } 1335d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao 1345d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao /** 1355d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * Sleeps for the "ms" milliseconds. 1365d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao */ 1375d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao public static void sleep(int ms) { 1385d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao try { 1395d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao Thread.sleep(ms); 1405d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao } catch (InterruptedException ie) { 1415d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao System.err.println("sleep was interrupted"); 1425d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao } 1435d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao } 1445d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao 1455d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao /** 1465d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * Sleeps briefly, allowing other threads some CPU time to get started. 1475d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao */ 1485d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao public static void startupDelay() { 1495d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao sleep(500); 1505d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao } 1515d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao} 1525d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao 1535d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao 1545d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao/** 1555d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * Allocates useless objects and holds on to several of them. 1565d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * 1575d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * Uses a single large array of references, replaced repeatedly in round-robin 1585d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * order. 1595d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao */ 1605d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhaoclass Robin extends Thread { 1615d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao private static final int ARRAY_SIZE = 40960; 1625d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao int sleepCount = 0; 1635d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao 1645d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao public void run() { 1655d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao Main.startupDelay(); 1665d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao 1675d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao String strings[] = new String[ARRAY_SIZE]; 1685d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao int idx = 0; 1695d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao 1705d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao while (!Main.quit) { 1715d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao strings[idx] = makeString(idx); 1725d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao 1735d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao if (idx % (ARRAY_SIZE / 4) == 0) { 1745d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao Main.sleep(400); 1755d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao sleepCount++; 1765d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao } 1775d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao 1785d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao idx = (idx + 1) % ARRAY_SIZE; 1795d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao } 1805d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao 1815d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao if (Main.DEBUG) 1825d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao System.out.println("Robin: sleepCount=" + sleepCount); 1835d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao } 1845d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao 1855d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao private String makeString(int val) { 186cecc2d91236cc0394c60eb09fd114342faa44f15Mathieu Chartier try { 187cecc2d91236cc0394c60eb09fd114342faa44f15Mathieu Chartier return new String("Robin" + val); 188cecc2d91236cc0394c60eb09fd114342faa44f15Mathieu Chartier } catch (OutOfMemoryError e) { 189cecc2d91236cc0394c60eb09fd114342faa44f15Mathieu Chartier return null; 190cecc2d91236cc0394c60eb09fd114342faa44f15Mathieu Chartier } 1915d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao } 1925d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao} 1935d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao 1945d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao 1955d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao/** 1965d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * Allocates useless objects in recursive calls. 1975d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao */ 1985d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhaoclass Deep extends Thread { 1995d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao private static final int MAX_DEPTH = 61; 2005d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao 2015d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao private static String strong[] = new String[MAX_DEPTH]; 2025d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao private static WeakReference weak[] = new WeakReference[MAX_DEPTH]; 2035d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao 2045d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao public void run() { 2055d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao int iter = 0; 2065d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao boolean once = false; 2075d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao 2085d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao Main.startupDelay(); 2095d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao 2105d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao while (!Main.quit) { 2115d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao dive(0, iter); 2125d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao once = true; 2135d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao iter += MAX_DEPTH; 2145d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao } 2155d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao 2165d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao if (!once) { 2175d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao System.err.println("not even once?"); 2185d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao return; 2195d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao } 2205d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao 2215ee9454dfee08a70dec62b0ed0fd4ad274274937Sebastien Hertz checkStringReferences(); 2225d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao 2235d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao /* 2245d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * Wipe "strong", do a GC, see if "weak" got collected. 2255d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao */ 2265d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao for (int i = 0; i < MAX_DEPTH; i++) 2275d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao strong[i] = null; 2285d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao 2297befd0e35bbed32b90bc0c8b6d3fa8bd612f5506Mathieu Chartier Runtime.getRuntime().gc(); 2305d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao 2315d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao for (int i = 0; i < MAX_DEPTH; i++) { 2325d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao if (weak[i].get() != null) { 2335d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao System.err.println("Deep: weak still has " + i); 2345d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao } 2355d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao } 2365d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao 2375d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao if (Main.DEBUG) 2385d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao System.out.println("Deep: iters=" + iter / MAX_DEPTH); 2395d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao } 2405d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao 2415ee9454dfee08a70dec62b0ed0fd4ad274274937Sebastien Hertz 2425ee9454dfee08a70dec62b0ed0fd4ad274274937Sebastien Hertz /** 2435ee9454dfee08a70dec62b0ed0fd4ad274274937Sebastien Hertz * Check the results of the last trip through. Everything in 2445ee9454dfee08a70dec62b0ed0fd4ad274274937Sebastien Hertz * "weak" should be matched in "strong", and the two should be 2455ee9454dfee08a70dec62b0ed0fd4ad274274937Sebastien Hertz * equivalent (object-wise, not just string-equality-wise). 2465ee9454dfee08a70dec62b0ed0fd4ad274274937Sebastien Hertz * 2475ee9454dfee08a70dec62b0ed0fd4ad274274937Sebastien Hertz * We do that check in a separate method to avoid retaining these 2485ee9454dfee08a70dec62b0ed0fd4ad274274937Sebastien Hertz * String references in local DEX registers. In interpreter mode, 2495ee9454dfee08a70dec62b0ed0fd4ad274274937Sebastien Hertz * they would retain these references until the end of the method 2505ee9454dfee08a70dec62b0ed0fd4ad274274937Sebastien Hertz * or until they are updated to another value. 2515ee9454dfee08a70dec62b0ed0fd4ad274274937Sebastien Hertz */ 2525ee9454dfee08a70dec62b0ed0fd4ad274274937Sebastien Hertz private static void checkStringReferences() { 2535ee9454dfee08a70dec62b0ed0fd4ad274274937Sebastien Hertz for (int i = 0; i < MAX_DEPTH; i++) { 2545ee9454dfee08a70dec62b0ed0fd4ad274274937Sebastien Hertz if (strong[i] != weak[i].get()) { 2555ee9454dfee08a70dec62b0ed0fd4ad274274937Sebastien Hertz System.err.println("Deep: " + i + " strong=" + strong[i] + 2565ee9454dfee08a70dec62b0ed0fd4ad274274937Sebastien Hertz ", weak=" + weak[i].get()); 2575ee9454dfee08a70dec62b0ed0fd4ad274274937Sebastien Hertz } 2585ee9454dfee08a70dec62b0ed0fd4ad274274937Sebastien Hertz } 2595ee9454dfee08a70dec62b0ed0fd4ad274274937Sebastien Hertz } 2605ee9454dfee08a70dec62b0ed0fd4ad274274937Sebastien Hertz 2615d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao /** 2625d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * Recursively dive down, setting one or more local variables. 2635d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * 2645d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * We pad the stack out with locals, attempting to create a mix of 2655d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * valid and invalid references on the stack. 2665d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao */ 2675d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao private String dive(int depth, int iteration) { 2689dc0cedd16027858a8d24be6cfc0af63031c22b5Mathieu Chartier try { 2699dc0cedd16027858a8d24be6cfc0af63031c22b5Mathieu Chartier String str0; 2709dc0cedd16027858a8d24be6cfc0af63031c22b5Mathieu Chartier String str1; 2719dc0cedd16027858a8d24be6cfc0af63031c22b5Mathieu Chartier String str2; 2729dc0cedd16027858a8d24be6cfc0af63031c22b5Mathieu Chartier String str3; 2739dc0cedd16027858a8d24be6cfc0af63031c22b5Mathieu Chartier String str4; 2749dc0cedd16027858a8d24be6cfc0af63031c22b5Mathieu Chartier String str5; 2759dc0cedd16027858a8d24be6cfc0af63031c22b5Mathieu Chartier String str6; 2769dc0cedd16027858a8d24be6cfc0af63031c22b5Mathieu Chartier String str7; 2779dc0cedd16027858a8d24be6cfc0af63031c22b5Mathieu Chartier String funStr = ""; 2789dc0cedd16027858a8d24be6cfc0af63031c22b5Mathieu Chartier switch (iteration % 8) { 2799dc0cedd16027858a8d24be6cfc0af63031c22b5Mathieu Chartier case 0: 2809dc0cedd16027858a8d24be6cfc0af63031c22b5Mathieu Chartier funStr = str0 = makeString(iteration); 2819dc0cedd16027858a8d24be6cfc0af63031c22b5Mathieu Chartier break; 2829dc0cedd16027858a8d24be6cfc0af63031c22b5Mathieu Chartier case 1: 2839dc0cedd16027858a8d24be6cfc0af63031c22b5Mathieu Chartier funStr = str1 = makeString(iteration); 2849dc0cedd16027858a8d24be6cfc0af63031c22b5Mathieu Chartier break; 2859dc0cedd16027858a8d24be6cfc0af63031c22b5Mathieu Chartier case 2: 2869dc0cedd16027858a8d24be6cfc0af63031c22b5Mathieu Chartier funStr = str2 = makeString(iteration); 2879dc0cedd16027858a8d24be6cfc0af63031c22b5Mathieu Chartier break; 2889dc0cedd16027858a8d24be6cfc0af63031c22b5Mathieu Chartier case 3: 2899dc0cedd16027858a8d24be6cfc0af63031c22b5Mathieu Chartier funStr = str3 = makeString(iteration); 2909dc0cedd16027858a8d24be6cfc0af63031c22b5Mathieu Chartier break; 2919dc0cedd16027858a8d24be6cfc0af63031c22b5Mathieu Chartier case 4: 2929dc0cedd16027858a8d24be6cfc0af63031c22b5Mathieu Chartier funStr = str4 = makeString(iteration); 2939dc0cedd16027858a8d24be6cfc0af63031c22b5Mathieu Chartier break; 2949dc0cedd16027858a8d24be6cfc0af63031c22b5Mathieu Chartier case 5: 2959dc0cedd16027858a8d24be6cfc0af63031c22b5Mathieu Chartier funStr = str5 = makeString(iteration); 2969dc0cedd16027858a8d24be6cfc0af63031c22b5Mathieu Chartier break; 2979dc0cedd16027858a8d24be6cfc0af63031c22b5Mathieu Chartier case 6: 2989dc0cedd16027858a8d24be6cfc0af63031c22b5Mathieu Chartier funStr = str6 = makeString(iteration); 2999dc0cedd16027858a8d24be6cfc0af63031c22b5Mathieu Chartier break; 3009dc0cedd16027858a8d24be6cfc0af63031c22b5Mathieu Chartier case 7: 3019dc0cedd16027858a8d24be6cfc0af63031c22b5Mathieu Chartier funStr = str7 = makeString(iteration); 3029dc0cedd16027858a8d24be6cfc0af63031c22b5Mathieu Chartier break; 3039dc0cedd16027858a8d24be6cfc0af63031c22b5Mathieu Chartier } 3045d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao 305ed8b53d679d46891d8d405b0ce4a48c282d872f7Nicolas Geoffray weak[depth] = new WeakReference(funStr); 30667f65ea9ca0826ff16397694bfb9c4858a958453Nicolas Geoffray strong[depth] = funStr; 3079dc0cedd16027858a8d24be6cfc0af63031c22b5Mathieu Chartier if (depth+1 < MAX_DEPTH) 3089dc0cedd16027858a8d24be6cfc0af63031c22b5Mathieu Chartier dive(depth+1, iteration+1); 3099dc0cedd16027858a8d24be6cfc0af63031c22b5Mathieu Chartier else 3109dc0cedd16027858a8d24be6cfc0af63031c22b5Mathieu Chartier Main.sleep(100); 3119dc0cedd16027858a8d24be6cfc0af63031c22b5Mathieu Chartier return funStr; 3129dc0cedd16027858a8d24be6cfc0af63031c22b5Mathieu Chartier } catch (OutOfMemoryError e) { 3139dc0cedd16027858a8d24be6cfc0af63031c22b5Mathieu Chartier // Silently ignore OOME since gc stress mode causes them to occur but shouldn't be a 3149dc0cedd16027858a8d24be6cfc0af63031c22b5Mathieu Chartier // test failure. 3159dc0cedd16027858a8d24be6cfc0af63031c22b5Mathieu Chartier } 3169dc0cedd16027858a8d24be6cfc0af63031c22b5Mathieu Chartier return ""; 3175d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao } 3185d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao 3195d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao private String makeString(int val) { 320cecc2d91236cc0394c60eb09fd114342faa44f15Mathieu Chartier try { 321cecc2d91236cc0394c60eb09fd114342faa44f15Mathieu Chartier return new String("Deep" + val); 322cecc2d91236cc0394c60eb09fd114342faa44f15Mathieu Chartier } catch (OutOfMemoryError e) { 323cecc2d91236cc0394c60eb09fd114342faa44f15Mathieu Chartier return null; 324cecc2d91236cc0394c60eb09fd114342faa44f15Mathieu Chartier } 3255d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao } 3265d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao} 3275d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao 3285d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao 3295d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao/** 3305d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * Allocates large useless objects. 3315d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao */ 3325d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhaoclass Large extends Thread { 3335d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao public void run() { 3345d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao byte[] chunk; 3355d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao int count = 0; 3365d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao int sleepCount = 0; 3375d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao 3385d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao Main.startupDelay(); 3395d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao 3405d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao while (!Main.quit) { 341cecc2d91236cc0394c60eb09fd114342faa44f15Mathieu Chartier try { 342cecc2d91236cc0394c60eb09fd114342faa44f15Mathieu Chartier chunk = new byte[100000]; 343cecc2d91236cc0394c60eb09fd114342faa44f15Mathieu Chartier pretendToUse(chunk); 344cecc2d91236cc0394c60eb09fd114342faa44f15Mathieu Chartier 345cecc2d91236cc0394c60eb09fd114342faa44f15Mathieu Chartier count++; 346cecc2d91236cc0394c60eb09fd114342faa44f15Mathieu Chartier if ((count % 500) == 0) { 347cecc2d91236cc0394c60eb09fd114342faa44f15Mathieu Chartier Main.sleep(400); 348cecc2d91236cc0394c60eb09fd114342faa44f15Mathieu Chartier sleepCount++; 349cecc2d91236cc0394c60eb09fd114342faa44f15Mathieu Chartier } 350cecc2d91236cc0394c60eb09fd114342faa44f15Mathieu Chartier } catch (OutOfMemoryError e) { 3515d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao } 3525d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao } 3535d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao 3545d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao if (Main.DEBUG) 3555d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao System.out.println("Large: sleepCount=" + sleepCount); 3565d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao } 3575d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao 3585d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao public void pretendToUse(byte[] chunk) {} 3595d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao} 360