java.lang.management パッケージ - GarbageCollectorMXBean インタフェース
ManagementFactory クラスを介して取得できるMXBeanの一つが実装するインタフェース。
- java.lang.management パッケージ - ManagementFactory クラス - HHeLiBeXの日記 正道編
- GarbageCollectorMXBean (Java 2 Platform SE 5.0)
このインタフェースは、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; } } } }
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
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"というのはなんだろうな‥よく分からないけど。