Package org.radargun.sysmonitor

Source Code of org.radargun.sysmonitor.GcMonitor

package org.radargun.sysmonitor;

import static java.lang.management.ManagementFactory.GARBAGE_COLLECTOR_MXBEAN_DOMAIN_TYPE;
import static java.lang.management.ManagementFactory.newPlatformMXBeanProxy;

import java.io.Serializable;
import java.lang.management.GarbageCollectorMXBean;
import java.lang.management.ManagementFactory;
import java.lang.management.OperatingSystemMXBean;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
import java.util.concurrent.TimeUnit;
import javax.management.MBeanServerConnection;
import javax.management.ObjectName;

import org.radargun.reporting.Timeline;
import org.radargun.traits.JmxConnectionProvider;

/**
* In each invocation of the {@link #run()} method, retrieves information
* about garbage collection from JMX and reports it into the {@link Timeline}.
*
* @author Galder Zamarreno
*/
public class GcMonitor extends JmxMonitor implements Serializable {
   private static final String GC_USAGE = "GC CPU usage";

   private long prevGcTime;
   private long prevUpTime;

   public GcMonitor(JmxConnectionProvider jmxConnectionProvider, Timeline timeline) {
      super(jmxConnectionProvider, timeline);
   }

   public synchronized void run() {
      try {
         if (connection == null) {
            log.warn("MBean connection is not open, cannot read GC stats");
            return;
         }

         OperatingSystemMXBean os = ManagementFactory.newPlatformMXBeanProxy(connection,
               ManagementFactory.OPERATING_SYSTEM_MXBEAN_NAME, OperatingSystemMXBean.class);
         int procCount = os.getAvailableProcessors();

         List<GarbageCollectorMXBean> gcMbeans = getGarbageCollectorMXBeans(connection);
         long gcTime = 0;
         for (GarbageCollectorMXBean gcBean : gcMbeans)
            gcTime += gcBean.getCollectionTime();

         long processGcTimeDiff = TimeUnit.MILLISECONDS.toNanos(gcTime - prevGcTime) / procCount;
         long upTime = (Long) connection.getAttribute(RUNTIME_NAME, PROCESS_UP_TIME);
         long upTimeDiff = TimeUnit.MILLISECONDS.toNanos(upTime - prevUpTime);

         double gcUsage = Math.min(1d, Math.max(0, (double) processGcTimeDiff / (double) upTimeDiff));

         timeline.addValue(GC_USAGE, new Timeline.Value(gcUsage));
         log.tracef("Current GC CPU usage: %.2f%%", 100 * gcUsage);
         prevUpTime = upTime;
         prevGcTime = gcTime;
      } catch (Exception e) {
         log.error(e.getMessage(), e);
      }
   }

   private List<GarbageCollectorMXBean> getGarbageCollectorMXBeans(MBeanServerConnection con) throws Exception {
      List<GarbageCollectorMXBean> gcMbeans = null;
      // TODO: List changes, so can't really cache apparently, but how performant is this?
      if (con != null) {
         ObjectName gcName = new ObjectName(GARBAGE_COLLECTOR_MXBEAN_DOMAIN_TYPE + ",*");
         Set<ObjectName> mbeans = con.queryNames(gcName, null);
         if (mbeans != null) {
            gcMbeans = new ArrayList<GarbageCollectorMXBean>();
            for (ObjectName on : mbeans) {
               String name = GARBAGE_COLLECTOR_MXBEAN_DOMAIN_TYPE + ",name=" + on.getKeyProperty("name");
               GarbageCollectorMXBean mbean = newPlatformMXBeanProxy(con, name, GarbageCollectorMXBean.class);
               gcMbeans.add(mbean);
            }
         }
      }
      return gcMbeans;
   }

   @Override
   public synchronized void start() {
      super.start();
      timeline.addValue(GC_USAGE, new Timeline.Value(0));
   }

   @Override
   public synchronized void stop() {
      super.stop();
      timeline.addValue(GC_USAGE, new Timeline.Value(0));
   }
}
TOP

Related Classes of org.radargun.sysmonitor.GcMonitor

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.