X

Poonam Bajaj's Blog

How to programmatically obtain GC information

Poonam Parhar
Consulting Member of Technical Staff
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.

Join the discussion

Comments ( 1 )
  • guest Friday, April 7, 2017

    My current requirement is below:

    Application will be running on the tomcat server, currently using JMX port we are using JConsole to capture GC information details.

    Now trying the same using API.

    How would i pass my JMX details to API so that i can access GC details.

    How to access current JVM runtimeMXbean?

    Tried with below but no luck.

    RuntimeMXBean mxbean = ManagementFactory.getRuntimeMXBean();

    List<GarbageCollectorMXBean> gcMxBean= (List<GarbageCollectorMXBean>)

    for (GarbageCollectorMXBean garbageCollectorMXBean : GCData.gcMxBean)

    {

    System.out.println("Alg name::" + garbageCollectorMXBean.getName());

    System.out.println("Memory pool names::" + garbageCollectorMXBean.getMemoryPoolNames());

    System.out.println("Collection Count::" + garbageCollectorMXBean.getCollectionCount());

    System.out.println("Collection Time::" + garbageCollectorMXBean.getCollectionTime());

    }


Please enter your name.Please provide a valid email address.Please enter a comment.CAPTCHA challenge response provided was incorrect. Please try again.