以编程方式打印启用GC日志记录时通常打印在JVM出口上的堆使用情况

时间:2012-06-12 14:46:10

标签: java jmx

当我的Java应用程序(Oracle JVM v1.6.0)启用了GC日志记录时,它通常会在退出时打印以下输出:

PSYoungGen      total 6429824K, used 5483163K [0x0000000640000000, 0x0000000800000000, 0x0000000800000000)
  eden space 5483456K, 99% used [0x0000000640000000,0x000000078eaa6cc0,0x000000078eaf0000)
  from space 946368K, 0% used [0x00000007c63d0000,0x00000007c63d0000,0x0000000800000000)
  to   space 910208K, 0% used [0x000000078eaf0000,0x000000078eaf0000,0x00000007c63d0000)
 ParOldGen       total 3145728K, used 3145724K [0x0000000580000000, 0x0000000640000000, 0x0000000640000000)
  object space 3145728K, 99% used [0x0000000580000000,0x000000063ffff3a0,0x0000000640000000)
 PSPermGen       total 57984K, used 57686K [0x000000057ac00000, 0x000000057e4a0000, 0x0000000580000000)
  object space 57984K, 99% used [0x000000057ac00000,0x000000057e455ae0,0x000000057e4a0000)

在应用程序运行期间是否有定期生成此输出的方法?我知道How do I access memory usage programmatically via JMX?但坦率地说,我希望有一个捷径,而不是重新实现产生上述代码的代码。例如,可能向JVM发送一个kill信号会强制输出上述输出吗?

2 个答案:

答案 0 :(得分:4)

MXBeans有什么问题?实施并不是那么难。

我用过类似的东西:

    List<GarbageCollectorMXBean> gcList = ManagementFactory.getGarbageCollectorMXBeans();
    for(GarbageCollectorMXBean tmpGC : gcList){

        System.out.println("\nName: " + tmpGC.getName());
        System.out.println("Collection count: " + tmpGC.getCollectionCount());
        System.out.println("Collection time: " + tmpGC.getCollectionTime());
        System.out.println("Memory Pools: ");

        String[] memoryPoolNames = tmpGC.getMemoryPoolNames();
        for(String mpnTmp : memoryPoolNames){
            System.out.println("\t" + mpnTmp);
        }

    }

    System.out.println( "Memory Pools Info" );
    List<MemoryPoolMXBean> memoryList = ManagementFactory.getMemoryPoolMXBeans();
    for(MemoryPoolMXBean tmpMem : memoryList){

        System.out.println("\nName: " + tmpMem.getName());
        System.out.println("Usage: " + tmpMem.getUsage());
        System.out.println("Collection Usage: " + tmpMem.getCollectionUsage());
        System.out.println("Peak Usage: " + tmpMem.getPeakUsage());
        System.out.println("Type: " + tmpMem.getType());
        System.out.println("Memory Manager Names: ") ;

        String[] memManagerNames = tmpMem.getMemoryManagerNames();
        for(String mmnTmp : memManagerNames){
            System.out.println("\t" + mmnTmp);
        }
        System.out.println("\n");
    }

    MemoryUsage mu =ManagementFactory.getMemoryMXBean().getHeapMemoryUsage();
    MemoryUsage muNH =ManagementFactory.getMemoryMXBean().getNonHeapMemoryUsage();
    System.out.println(
            "Init :"+mu.getInit()+
            "\nMax :"+mu.getMax()+
            "\nUsed :"+mu.getUsed()+
            "\nCommited :"+mu.getCommitted()+
            "\nInit NH :"+muNH.getInit()+
            "\nMax NH :"+muNH.getMax()+
            "\nUsed NH:"+muNH.getUsed()+
            "\nCommited NH:"+muNH.getCommitted());

答案 1 :(得分:2)

您可以使用选项启动JVM以控制此类信息的运行时输出。

请参阅java tool documentation

例如输出到控制台:

java -verbose:gc

或输出到文件:

java -Xloggc:your.log.file

使用其中任何一个选项,JVM会在VM运行时记录每个GC事件(而不仅仅是退出时)。