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) {
1865d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        return new String("Robin" + val);
1875d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    }
1885d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao}
1895d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
1905d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
1915d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao/**
1925d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * Allocates useless objects in recursive calls.
1935d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao */
1945d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhaoclass Deep extends Thread {
1955d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    private static final int MAX_DEPTH = 61;
1965d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
1975d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    private static String strong[] = new String[MAX_DEPTH];
1985d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    private static WeakReference weak[] = new WeakReference[MAX_DEPTH];
1995d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
2005d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    public void run() {
2015d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        int iter = 0;
2025d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        boolean once = false;
2035d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
2045d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        Main.startupDelay();
2055d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
2065d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        while (!Main.quit) {
2075d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            dive(0, iter);
2085d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            once = true;
2095d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            iter += MAX_DEPTH;
2105d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        }
2115d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
2125d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        if (!once) {
2135d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.err.println("not even once?");
2145d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            return;
2155d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        }
2165d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
2175d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        /*
2185d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao         * Check the results of the last trip through.  Everything in
2195d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao         * "weak" should be matched in "strong", and the two should be
2205d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao         * equivalent (object-wise, not just string-equality-wise).
2215d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao         */
2225d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        for (int i = 0; i < MAX_DEPTH; i++) {
2235d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            if (strong[i] != weak[i].get()) {
2245d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao                System.err.println("Deep: " + i + " strong=" + strong[i] +
2255d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao                    ", weak=" + weak[i].get());
2265d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            }
2275d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        }
2285d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
2295d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        /*
2305d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao         * Wipe "strong", do a GC, see if "weak" got collected.
2315d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao         */
2325d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        for (int i = 0; i < MAX_DEPTH; i++)
2335d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            strong[i] = null;
2345d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
2355d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        System.gc();
2365d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
2375d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        for (int i = 0; i < MAX_DEPTH; i++) {
2385d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            if (weak[i].get() != null) {
2395d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao                System.err.println("Deep: weak still has " + i);
2405d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            }
2415d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        }
2425d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
2435d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        if (Main.DEBUG)
2445d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.out.println("Deep: iters=" + iter / MAX_DEPTH);
2455d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    }
2465d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
2475d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    /**
2485d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao     * Recursively dive down, setting one or more local variables.
2495d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao     *
2505d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao     * We pad the stack out with locals, attempting to create a mix of
2515d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao     * valid and invalid references on the stack.
2525d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao     */
2535d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    private String dive(int depth, int iteration) {
2545d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        String str0;
2555d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        String str1;
2565d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        String str2;
2575d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        String str3;
2585d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        String str4;
2595d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        String str5;
2605d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        String str6;
2615d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        String str7;
2625d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        String funStr;
2635d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
2645d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        funStr = "";
2655d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
2665d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        switch (iteration % 8) {
2675d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            case 0:
2685d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao                funStr = str0 = makeString(iteration);
2695d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao                break;
2705d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            case 1:
2715d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao                funStr = str1 = makeString(iteration);
2725d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao                break;
2735d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            case 2:
2745d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao                funStr = str2 = makeString(iteration);
2755d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao                break;
2765d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            case 3:
2775d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao                funStr = str3 = makeString(iteration);
2785d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao                break;
2795d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            case 4:
2805d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao                funStr = str4 = makeString(iteration);
2815d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao                break;
2825d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            case 5:
2835d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao                funStr = str5 = makeString(iteration);
2845d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao                break;
2855d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            case 6:
2865d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao                funStr = str6 = makeString(iteration);
2875d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao                break;
2885d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            case 7:
2895d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao                funStr = str7 = makeString(iteration);
2905d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao                break;
2915d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        }
2925d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
2935d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        strong[depth] = funStr;
2945d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        weak[depth] = new WeakReference(funStr);
2955d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
2965d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        if (depth+1 < MAX_DEPTH)
2975d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            dive(depth+1, iteration+1);
2985d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        else
2995d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            Main.sleep(100);
3005d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
3015d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        return funStr;
3025d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    }
3035d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
3045d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    private String makeString(int val) {
3055d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        return new String("Deep" + val);
3065d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    }
3075d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao}
3085d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
3095d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
3105d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao/**
3115d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao * Allocates large useless objects.
3125d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao */
3135d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhaoclass Large extends Thread {
3145d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    public void run() {
3155d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        byte[] chunk;
3165d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        int count = 0;
3175d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        int sleepCount = 0;
3185d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
3195d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        Main.startupDelay();
3205d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
3215d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        while (!Main.quit) {
3225d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            chunk = new byte[100000];
3235d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            pretendToUse(chunk);
3245d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
3255d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            count++;
3265d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            if ((count % 500) == 0) {
3275d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao                Main.sleep(400);
3285d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao                sleepCount++;
3295d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            }
3305d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        }
3315d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
3325d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao        if (Main.DEBUG)
3335d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao            System.out.println("Large: sleepCount=" + sleepCount);
3345d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    }
3355d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao
3365d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao    public void pretendToUse(byte[] chunk) {}
3375d1ac920fdaef5d4ec8f66bb734488cd9660b024jeffhao}
338