Wednesday Apr 22, 2015

Throughput collector and PrintTenuringDistribution option

This is going to be a very short blog post. The inspiration for this post is a customer report that the PrintTenuringDistribution option does not show age information with the throughput collector (Parallel or Parallel Old GC).

2.798: [GC
Desired survivor size 11534336 bytes, new threshold 7 (max 15)
[PSYoungGen: 67584K->9802K(78848K)] 67584K->9810K(254976K), 0.0467029 secs]
[Times: user=0.07 sys=0.02, real=0.05 secs]
3.604: [GC
Desired survivor size 11534336 bytes, new threshold 7 (max 15)
[PSYoungGen: 77386K->11156K(146432K)] 77394K->11236K(322560K), 0.0436806 secs]


Well, this is the expected behavior and is not a bug. Throughput collector does not use the age table like the other collectors do. And due to that reason, the age histogram information is not printed with the throughput collector. With the throughput collector, we can only see the desired survivor size, threshold age, and the maximum threshold age with PrintTenuringDistribution option.

Thursday Jul 05, 2007

How to programmatically obtain GC information

Here's a small program which uses GarbageCollectorMXBean MBean to programmatically obtain the GC information of the running java process. Call it's printGCInfo in your applcation whenever you want to get the last GC information.
import com.sun.management.GcInfo;
import javax.management.MBeanServer;
import java.lang.management.ManagementFactory;
import com.sun.management.GarbageCollectorMXBean;
import java.lang.management.MemoryUsage;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;

public class GCInformation {
    
    private static final String GC_BEAN_NAME =
         "java.lang:type=GarbageCollector,name=ConcurrentMarkSweep";
    private static volatile GarbageCollectorMXBean gcMBean;
    
    /\*\* Creates a new instance of GCInformation \*/
    public GCInformation() {
    }
    
    // initialize the GC MBean field
    private static void initGCMBean() {
        if (gcMBean == null) {
            synchronized (GCInformation.class) {
                if (gcMBean == null) {
                    gcMBean = getGCMBean();
                }
            }
        }
    }    
    // get the GarbageCollectorMXBean MBean from the
    // platform MBean server
    private static GarbageCollectorMXBean getGCMBean() {
        try {
            MBeanServer server = ManagementFactory.getPlatformMBeanServer();
            GarbageCollectorMXBean bean = 
                ManagementFactory.newPlatformMXBeanProxy(server,
                GC_BEAN_NAME, GarbageCollectorMXBean.class);
            return bean;
        } catch (RuntimeException re) {
            throw re;
        } catch (Exception exp) {
            throw new RuntimeException(exp);
        }
    }
    
    /\*\*
     \* Call this method from your application whenever you 
     \* want to get the last gc info
     \*
     \*/
    static boolean printGCInfo() {
        // initialize GC MBean
        initGCMBean();
        try {
            GcInfo gci = gcMBean.getLastGcInfo();
            long id = gci.getId();
            long startTime = gci.getStartTime();
            long endTime = gci.getEndTime();
            long duration = gci.getDuration();
            
            if (startTime == endTime) {
                return false;   // no gc
            }
            System.out.println("GC ID: "+id);
            System.out.println("Start Time: "+startTime);
            System.out.println("End Time: "+endTime);
            System.out.println("Duration: "+duration);
            Map mapBefore = gci.getMemoryUsageBeforeGc();
            Map mapAfter = gci.getMemoryUsageAfterGc();

            System.out.println("Before GC Memory Usage Details....");
            Set memType = mapBefore.keySet();
            Iterator it = memType.iterator();
            while(it.hasNext()) {
                String type = (String)it.next();
                System.out.println(type);
                MemoryUsage mu1 = mapBefore.get(type);
                System.out.print("Initial Size: "+mu1.getInit());
                System.out.print(" Used: "+ mu1.getUsed());
                System.out.print(" Max: "+mu1.getMax());
                System.out.print(" Committed: "+mu1.getCommitted());
                System.out.println(" ");
            }
            
            System.out.println("After GC Memory Usage Details....");
            memType = mapAfter.keySet();
            it = memType.iterator();
            while(it.hasNext()) {
                String type = (String)it.next();
                System.out.println(type);
                MemoryUsage mu2 = mapAfter.get(type);
                System.out.print("Initial Size: "+mu2.getInit());
                System.out.print(" Used: "+ mu2.getUsed());
                System.out.print(" Max: "+mu2.getMax());
                System.out.print(" Committed: "+mu2.getCommitted());
                System.out.println(" ");
            }
        } catch (RuntimeException re) {
            throw re;
        } catch (Exception exp) {
            throw new RuntimeException(exp);
        }
        return true;
    }
    
    /\*\*
     \* @param args the command line arguments
     \*/
    public static void main(String[] args) {
        // Print the last gc information
        boolean ret = printGCInfo();        
    }    
}
Note that the GarbageCollector name used here is "ConcurrentMarkSweep" because I was running my appication with Concurrent Mark Sweep collector. Please use the appropriate Collector name from the list of Collector names I had posted in my previous entry.
About

Poonam-Oracle

Search

Categories
Archives
« September 2015
SunMonTueWedThuFriSat
  
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
   
       
Today