HHeLiBeXの日記 正道編

日々の記憶の記録とメモ‥

java.lang.management パッケージ - GarbageCollectorMXBean インタフェース

ManagementFactory クラスを介して取得できるMXBeanの一つが実装するインタフェース。

このインタフェースは、MemoryManagerMXBeanインタフェースのサブインタフェースで、Java VMのメモリマネージャのうち、ガベージコレクターに関するものを扱う。
とりあえず実際に実行してみる。
今回用いたのも、次のJava VM

import java.lang.management.GarbageCollectorMXBean;
import java.lang.management.ManagementFactory;
import java.util.ArrayList;
import java.util.List;

public class Main {

    /**
     * @param args
     */
    public static void main(String[] args) {
        System.out.printf("%-20s = %s\n", "java.version", System.getProperty("java.version"));
        System.out.printf("%-20s = %s\n", "java.vendor", System.getProperty("java.vendor"));
        System.out.printf("%-20s = %s\n", "java.runtime.version", System.getProperty("java.runtime.version"));
        System.out.printf("%-20s = %s\n", "os.name", System.getProperty("os.name"));

        System.out.println("0: ========");
        printGarbageCollectorInfo(true);

        System.out.println("1: ========");
        printGarbageCollectorInfo(false);

        /*
         * OutOfMemoryErrorを発生させて、GCの実行状況を見る。
         */
        try {
            List<Object> list = new ArrayList<Object>();
            for (int i = 0; i < 10000000; ++i) {
                list.add(new Object());
            }
        } catch (Throwable e) {
            e.printStackTrace(System.out);
        }
        System.out.println("2: ========");
        printGarbageCollectorInfo(false);

        System.out.println("3: ========");
        printGarbageCollectorInfo(false);

        /*
         * OutOfMemoryErrorが発生しない範囲でヒープメモリを消費し、
         * その後ほうっておいたときのGCの実行状況を見る。
         */
        try {
            List<Object> list = new ArrayList<Object>();
            for (int i = 0; i < 1000000; ++i) {
                list.add(new Object());
            }
        } catch (Throwable e) {
            e.printStackTrace(System.out);
        }
        System.out.println("4: ========");
        printGarbageCollectorInfo(false);

        /*
         * System.gc()メソッドを呼び出してみる。
         * 分かりやすいように中途半端な回数。
         */
        for (int i = 0; i < 123; ++i) {
            System.gc();
        }
        System.out.println("5: ========");
        printGarbageCollectorInfo(false);
    }

    private static void printGarbageCollectorInfo(boolean detail) {
        List<GarbageCollectorMXBean> garbageCollectorMXBeans = ManagementFactory.getGarbageCollectorMXBeans();
        System.out.printf("%-20s: %s\n", "# of MXBeans", garbageCollectorMXBeans.size());
        {
            int i = 0;
            for (GarbageCollectorMXBean garbageCollectorMXBean : garbageCollectorMXBeans) {
                System.out.printf("[%2d]\n", i);
                System.out.printf("    %-24s: %s\n", "name", garbageCollectorMXBean.getName());
                System.out.printf("    %-24s: %s\n", "collectionCount", garbageCollectorMXBean.getCollectionCount());
                System.out.printf("    %-24s: %s\n", "collectionTime", garbageCollectorMXBean.getCollectionTime());
                if (detail) {
                    String[] memoryPoolNames = garbageCollectorMXBean.getMemoryPoolNames();
                    System.out.printf("    %-24s: %s\n", "memoryPoolNames.length", memoryPoolNames.length);
                    for (int j = 0; j < memoryPoolNames.length; ++j) {
                        System.out.printf("        %-20s[%2d]: %s\n", "memoryPoolName", j, memoryPoolNames[j]);
                    }
                    System.out.printf("    %-24s: %s\n", "isValid", garbageCollectorMXBean.isValid());
                }

                ++i;
            }
        }
    }

}

Sun Java 2 SDK 1.5.0_11

java.version         = 1.5.0_11
java.vendor          = Sun Microsystems Inc.
java.runtime.version = 1.5.0_11-b03
os.name              = Windows Vista
0: ========
# of MXBeans        : 2
[ 0]
    name                    : Copy
    collectionCount         : 0
    collectionTime          : 0
    memoryPoolNames.length  : 2
        memoryPoolName      [ 0]: Eden Space
        memoryPoolName      [ 1]: Survivor Space
    isValid                 : true
[ 1]
    name                    : MarkSweepCompact
    collectionCount         : 0
    collectionTime          : 0
    memoryPoolNames.length  : 6
        memoryPoolName      [ 0]: Eden Space
        memoryPoolName      [ 1]: Survivor Space
        memoryPoolName      [ 2]: Tenured Gen
        memoryPoolName      [ 3]: Perm Gen
        memoryPoolName      [ 4]: Perm Gen [shared-ro]
        memoryPoolName      [ 5]: Perm Gen [shared-rw]
    isValid                 : true
1: ========
# of MXBeans        : 2
[ 0]
    name                    : Copy
    collectionCount         : 0
    collectionTime          : 0
[ 1]
    name                    : MarkSweepCompact
    collectionCount         : 0
    collectionTime          : 0
java.lang.OutOfMemoryError: Java heap space
2: ========
# of MXBeans        : 2
[ 0]
    name                    : Copy
    collectionCount         : 28
    collectionTime          : 3095
[ 1]
    name                    : MarkSweepCompact
    collectionCount         : 1
    collectionTime          : 498
3: ========
# of MXBeans        : 2
[ 0]
    name                    : Copy
    collectionCount         : 28
    collectionTime          : 3095
[ 1]
    name                    : MarkSweepCompact
    collectionCount         : 1
    collectionTime          : 498
4: ========
# of MXBeans        : 2
[ 0]
    name                    : Copy
    collectionCount         : 33
    collectionTime          : 3354
[ 1]
    name                    : MarkSweepCompact
    collectionCount         : 1
    collectionTime          : 498
5: ========
# of MXBeans        : 2
[ 0]
    name                    : Copy
    collectionCount         : 33
    collectionTime          : 3354
[ 1]
    name                    : MarkSweepCompact
    collectionCount         : 124
    collectionTime          : 2556

IBM Java 2 SDK 1.5.0 SR10

java.version         = 1.5.0
java.vendor          = IBM Corporation
java.runtime.version = pwi32dev-20090707 (SR10 )
os.name              = Windows Vista
0: ========
# of MXBeans        : 1
[ 0]
    name                    : J9 GC
    collectionCount         : 0
    collectionTime          : 0
    memoryPoolNames.length  : 1
        memoryPoolName      [ 0]: Java heap
    isValid                 : true
1: ========
# of MXBeans        : 1
[ 0]
    name                    : J9 GC
    collectionCount         : 0
    collectionTime          : 0
java.lang.OutOfMemoryError
    at y2009.m11.d01.t002.Main.main(Main.java:28)
2: ========
# of MXBeans        : 1
[ 0]
    name                    : J9 GC
    collectionCount         : 22
    collectionTime          : 9371
3: ========
# of MXBeans        : 1
[ 0]
    name                    : J9 GC
    collectionCount         : 22
    collectionTime          : 9371
4: ========
# of MXBeans        : 1
[ 0]
    name                    : J9 GC
    collectionCount         : 22
    collectionTime          : 9371
5: ========
# of MXBeans        : 1
[ 0]
    name                    : J9 GC
    collectionCount         : 145
    collectionTime          : 29365

SunのJava VMでの実行結果から、OutOfMemoryErrorが発生しそうな状況になると"MarkSweepCompact"(Mark, Sweep and Compact)が実行されるのだろうな、というのが分かる。また、System.gc()メソッドを呼び出したときも同様らしい。JavaDocによると、MarkSweepCompactの実行は必須ではないようだが、今回試した実装では必ず実行されている感じだ。
一方、"Copy"というのはなんだろうな‥よく分からないけど。