4

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?

Community
  • 1
  • 1
noahlz
  • 10,202
  • 7
  • 56
  • 75
  • 2
    I assume you know how to programmatically get GC stats so you could write your own output. See here: http://stackoverflow.com/questions/466878/can-you-get-basic-gc-stats-in-java – Gray Jun 12 '12 at 14:49
  • I'm hoping for a shortcut that doesn't involve hand-writing JMX code. – noahlz Jun 12 '12 at 14:57
  • You don't have to hand write JMX code per se. You are just using JMX beans programmatically to get the information. You would have to write the class that does it. If that's what you want I'll add an answer with some sample code for you to try. – Gray Jun 12 '12 at 15:03

2 Answers2

4

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());
alain.janinm
  • 19,951
  • 10
  • 65
  • 112
  • 2
    Looks like this is the answer, aka "No, you can't, you have to write code to reproduce that output." – noahlz Jun 16 '12 at 04:10
2

You can launch the JVM with options to control runtime output of this kind of information.

See the java tool documentation.

For example to ouput to the console:

java -verbose:gc

or to output to file:

java -Xloggc:your.log.file

With either of these options, the JVM logs every GC event while the VM is running (not just when it exits).

ewan.chalmers
  • 16,145
  • 43
  • 60
  • That's how I get the above output. However, I want to generate the end-of-run heap summary periodically before program exit. – noahlz Jun 12 '12 at 14:57
  • With those command line args, the JVM logs every GC event. So if you are only getting one at close, I guess there is not much GC going on. – ewan.chalmers Jun 12 '12 at 15:04
  • 1
    No, I'm getting incremental GC events, but what I'm looking for is the output and format that I provided, which only seems to occur on program exit. – noahlz Jun 12 '12 at 15:14