Programmatically print the heap usage that is typically printed on JVM exit when GC logging is enabled

java, jmx

Solution

What's wrong with MXBeans? The implementation is not so hard.

I've used something like that :

    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());

Problem

When my Java application (Oracle JVM v1.6.0) has GC logging enabled, it typically prints the following output on exit: ``` 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) ``` Is there a method to generate this output periodically during the application run? I am aware of How do I access memory usage programmatically via JMX? but frankly I'm hoping for a shortcut vs. re-implementing the code that generates the above. For example, perhaps sending a kill signal to the JVM will force the above output?

Original source

Related problems