Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Android/art/art/test/074-gc-thrash/src/   (Android Betriebssystem Version 17©)  Datei vom 26.5.2026 mit Größe 9 kB image not shown  

Quelle  Main.java

  Sprache: JAVA
 

/*
 * 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.out.println(iae);
            } catch (InvocationTargetException ite) {
                System.out.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", String.class);
        } catch (NoSuchMethodException nsme) {
            System.out.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.out.println("join was interrupted");
        }
    }

    /**
     * Sleeps for the "ms" milliseconds.
     */

    public static void sleep(int ms) {
        try {
            Thread.sleep(ms);
        } catch (InterruptedException ie) {
            System.out.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) {
        try {
            return new String("Robin" + val);
        } catch (OutOfMemoryError e) {
            return null;
        }
    }
}


/**
 * Allocates useless objects in recursive calls.
 */

class Deep extends Thread {
    private static final int MAX_DEPTH = 50;

    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.out.println("not even once?");
            return;
        }

        checkStringReferences();

        /*
         * Wipe "strong", do a GC, see if "weak" got collected.
         */

        for (int i = 0; i < MAX_DEPTH; i++)
            strong[i] = null;

        Runtime.getRuntime().gc();

        for (int i = 0; i < MAX_DEPTH; i++) {
            if (weak[i].get() != null) {
                System.out.println("Deep: weak still has " + i);
            }
        }

        if (Main.DEBUG)
            System.out.println("Deep: iters=" + iter / MAX_DEPTH);
    }


    /**
     * 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).
     *
     * We do that check in a separate method to avoid retaining these
     * String references in local DEX registers. In interpreter mode,
     * they would retain these references until the end of the method
     * or until they are updated to another value.
     */

    private static void checkStringReferences() {
      for (int i = 0; i < MAX_DEPTH; i++) {
          if (strong[i] != weak[i].get()) {
              System.out.println("Deep: " + i + " strong=" + strong[i] +
                  ", weak=" + weak[i].get());
          }
      }
    }

    /**
     * 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) {
        try {
            String str0;
            String str1;
            String str2;
            String str3;
            String str4;
            String str5;
            String str6;
            String str7;
            String 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;
            }

            weak[depth] = new WeakReference(funStr);
            strong[depth] = funStr;
            if (depth+1 < MAX_DEPTH)
                dive(depth+1, iteration+1);
            else
                Main.sleep(100);
            return funStr;
        } catch (OutOfMemoryError e) {
            // Silently ignore OOME since gc stress mode causes them to occur but shouldn't be a
            // test failure.
        }
        return "";
    }

    private String makeString(int val) {
        try {
            return new String("Deep" + val);
        } catch (OutOfMemoryError e) {
            return null;
        }
    }
}


/**
 * Allocates large useless objects.
 */

class Large extends Thread {
    public void run() {
        byte[] chunk;
        int count = 0;
        int sleepCount = 0;

        Main.startupDelay();

        while (!Main.quit) {
            try {
                chunk = new byte[100000];
                pretendToUse(chunk);

                count++;
                if ((count % 500) == 0) {
                    Main.sleep(400);
                    sleepCount++;
                }
            } catch (OutOfMemoryError e) {
            }
        }

        if (Main.DEBUG)
            System.out.println("Large: sleepCount=" + sleepCount);
    }

    public void pretendToUse(byte[] chunk) {}
}

Messung V0.5 in Prozent
C=85 H=97 G=91

¤ Dauer der Verarbeitung: 0.11 Sekunden  (vorverarbeitet am  2026-06-29) ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

PVS Prover

Isabelle Prover

NIST Cobol Testsuite

Cephes Mathematical Library

Vienna Development Method

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.