summaryrefslogtreecommitdiffstats
path: root/tests/074-gc-thrash/src/Main.java
diff options
context:
space:
mode:
Diffstat (limited to 'tests/074-gc-thrash/src/Main.java')
-rw-r--r--tests/074-gc-thrash/src/Main.java337
1 files changed, 0 insertions, 337 deletions
diff --git a/tests/074-gc-thrash/src/Main.java b/tests/074-gc-thrash/src/Main.java
deleted file mode 100644
index f85aa4bde..000000000
--- a/tests/074-gc-thrash/src/Main.java
+++ /dev/null
@@ -1,337 +0,0 @@
-/*
- * 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.io.File;
-import java.lang.ref.WeakReference;
-import java.lang.reflect.Method;
-import java.lang.reflect.InvocationTargetException;
-
-public class Main {
- public static volatile boolean quit = false;
- public static final boolean DEBUG = false;
-
- private static final boolean WRITE_HPROF_DATA = false;
- private static final int TEST_TIME = 10;
- private static final String OUTPUT_FILE = "gc-thrash.hprof";
-
- public static void main(String[] args) {
- // dump heap before
-
- System.out.println("Running (" + TEST_TIME + " seconds) ...");
- runTests();
-
- Method dumpHprofDataMethod = null;
- String dumpFile = null;
-
- if (WRITE_HPROF_DATA) {
- dumpHprofDataMethod = getDumpHprofDataMethod();
- if (dumpHprofDataMethod != null) {
- dumpFile = getDumpFileName();
- System.out.println("Sending output to " + dumpFile);
- }
- }
-
- System.gc();
- System.runFinalization();
- System.gc();
-
- if (WRITE_HPROF_DATA && dumpHprofDataMethod != null) {
- try {
- dumpHprofDataMethod.invoke(null, dumpFile);
- } catch (IllegalAccessException iae) {
- System.err.println(iae);
- } catch (InvocationTargetException ite) {
- System.err.println(ite);
- }
- }
-
- System.out.println("Done.");
- }
-
- /**
- * Finds VMDebug.dumpHprofData() through reflection. In the reference
- * implementation this will not be available.
- *
- * @return the reflection object, or null if the method can't be found
- */
- private static Method getDumpHprofDataMethod() {
- ClassLoader myLoader = Main.class.getClassLoader();
- Class vmdClass;
- try {
- vmdClass = myLoader.loadClass("dalvik.system.VMDebug");
- } catch (ClassNotFoundException cnfe) {
- return null;
- }
-
- Method meth;
- try {
- meth = vmdClass.getMethod("dumpHprofData",
- new Class[] { String.class });
- } catch (NoSuchMethodException nsme) {
- System.err.println("Found VMDebug but not dumpHprofData method");
- return null;
- }
-
- return meth;
- }
-
- private static String getDumpFileName() {
- File tmpDir = new File("/tmp");
- if (tmpDir.exists() && tmpDir.isDirectory()) {
- return "/tmp/" + OUTPUT_FILE;
- }
-
- File sdcard = new File("/sdcard");
- if (sdcard.exists() && sdcard.isDirectory()) {
- return "/sdcard/" + OUTPUT_FILE;
- }
-
- return null;
- }
-
-
- /**
- * Run the various tests for a set period.
- */
- public static void runTests() {
- Robin robin = new Robin();
- Deep deep = new Deep();
- Large large = new Large();
-
- /* start all threads */
- robin.start();
- deep.start();
- large.start();
-
- /* let everybody run for 10 seconds */
- sleep(TEST_TIME * 1000);
-
- quit = true;
-
- try {
- /* wait for all threads to stop */
- robin.join();
- deep.join();
- large.join();
- } catch (InterruptedException ie) {
- System.err.println("join was interrupted");
- }
- }
-
- /**
- * Sleeps for the "ms" milliseconds.
- */
- public static void sleep(int ms) {
- try {
- Thread.sleep(ms);
- } catch (InterruptedException ie) {
- System.err.println("sleep was interrupted");
- }
- }
-
- /**
- * Sleeps briefly, allowing other threads some CPU time to get started.
- */
- public static void startupDelay() {
- sleep(500);
- }
-}
-
-
-/**
- * Allocates useless objects and holds on to several of them.
- *
- * Uses a single large array of references, replaced repeatedly in round-robin
- * order.
- */
-class Robin extends Thread {
- private static final int ARRAY_SIZE = 40960;
- int sleepCount = 0;
-
- public void run() {
- Main.startupDelay();
-
- String strings[] = new String[ARRAY_SIZE];
- int idx = 0;
-
- while (!Main.quit) {
- strings[idx] = makeString(idx);
-
- if (idx % (ARRAY_SIZE / 4) == 0) {
- Main.sleep(400);
- sleepCount++;
- }
-
- idx = (idx + 1) % ARRAY_SIZE;
- }
-
- if (Main.DEBUG)
- System.out.println("Robin: sleepCount=" + sleepCount);
- }
-
- private String makeString(int val) {
- return new String("Robin" + val);
- }
-}
-
-
-/**
- * Allocates useless objects in recursive calls.
- */
-class Deep extends Thread {
- private static final int MAX_DEPTH = 61;
-
- private static String strong[] = new String[MAX_DEPTH];
- private static WeakReference weak[] = new WeakReference[MAX_DEPTH];
-
- public void run() {
- int iter = 0;
- boolean once = false;
-
- Main.startupDelay();
-
- while (!Main.quit) {
- dive(0, iter);
- once = true;
- iter += MAX_DEPTH;
- }
-
- if (!once) {
- System.err.println("not even once?");
- return;
- }
-
- /*
- * Check the results of the last trip through. Everything in
- * "weak" should be matched in "strong", and the two should be
- * equivalent (object-wise, not just string-equality-wise).
- */
- for (int i = 0; i < MAX_DEPTH; i++) {
- if (strong[i] != weak[i].get()) {
- System.err.println("Deep: " + i + " strong=" + strong[i] +
- ", weak=" + weak[i].get());
- }
- }
-
- /*
- * Wipe "strong", do a GC, see if "weak" got collected.
- */
- for (int i = 0; i < MAX_DEPTH; i++)
- strong[i] = null;
-
- System.gc();
-
- for (int i = 0; i < MAX_DEPTH; i++) {
- if (weak[i].get() != null) {
- System.err.println("Deep: weak still has " + i);
- }
- }
-
- if (Main.DEBUG)
- System.out.println("Deep: iters=" + iter / MAX_DEPTH);
- }
-
- /**
- * Recursively dive down, setting one or more local variables.
- *
- * We pad the stack out with locals, attempting to create a mix of
- * valid and invalid references on the stack.
- */
- private String dive(int depth, int iteration) {
- String str0;
- String str1;
- String str2;
- String str3;
- String str4;
- String str5;
- String str6;
- String str7;
- String funStr;
-
- funStr = "";
-
- switch (iteration % 8) {
- case 0:
- funStr = str0 = makeString(iteration);
- break;
- case 1:
- funStr = str1 = makeString(iteration);
- break;
- case 2:
- funStr = str2 = makeString(iteration);
- break;
- case 3:
- funStr = str3 = makeString(iteration);
- break;
- case 4:
- funStr = str4 = makeString(iteration);
- break;
- case 5:
- funStr = str5 = makeString(iteration);
- break;
- case 6:
- funStr = str6 = makeString(iteration);
- break;
- case 7:
- funStr = str7 = makeString(iteration);
- break;
- }
-
- strong[depth] = funStr;
- weak[depth] = new WeakReference(funStr);
-
- if (depth+1 < MAX_DEPTH)
- dive(depth+1, iteration+1);
- else
- Main.sleep(100);
-
- return funStr;
- }
-
- private String makeString(int val) {
- return new String("Deep" + val);
- }
-}
-
-
-/**
- * Allocates large useless objects.
- */
-class Large extends Thread {
- public void run() {
- byte[] chunk;
- int count = 0;
- int sleepCount = 0;
-
- Main.startupDelay();
-
- while (!Main.quit) {
- chunk = new byte[100000];
- pretendToUse(chunk);
-
- count++;
- if ((count % 500) == 0) {
- Main.sleep(400);
- sleepCount++;
- }
- }
-
- if (Main.DEBUG)
- System.out.println("Large: sleepCount=" + sleepCount);
- }
-
- public void pretendToUse(byte[] chunk) {}
-}