package org.radargun.sysmonitor;
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
import java.lang.management.MemoryUsage;
import java.text.NumberFormat;
import org.radargun.reporting.Timeline;
import org.radargun.traits.JmxConnectionProvider;
/**
* In each invocation of the {@link #run()} method, retrieves information
* about memory size and usage from JMX and reports it into the {@link Timeline}.
*
* @author Galder Zamarreno
*/
public class MemoryUsageMonitor extends JmxMonitor {
private static final String MEMORY_USAGE = "Memory usage";
private static final NumberFormat DECIMAL_FORMATTER = NumberFormat.getNumberInstance();
static {
DECIMAL_FORMATTER.setGroupingUsed(true);
DECIMAL_FORMATTER.setMaximumFractionDigits(2);
}
public MemoryUsageMonitor(JmxConnectionProvider jmxConnectionProvider, Timeline timeline) {
super(jmxConnectionProvider, timeline);
}
public synchronized void run() {
try {
if (connection == null) {
log.warn("MBean connection is not open, cannot read memory stats");
return;
}
MemoryMXBean memMbean = ManagementFactory.newPlatformMXBeanProxy(connection, ManagementFactory.MEMORY_MXBEAN_NAME,
MemoryMXBean.class);
MemoryUsage mem = memMbean.getHeapMemoryUsage();
timeline.addValue(Timeline.Category.sysCategory(MEMORY_USAGE), new Timeline.Value(mem.getUsed() / 1048576));
log.trace("Memory usage: used=" + formatDecimal(mem.getUsed()) + " B, size=" + formatDecimal(mem.getCommitted())
+ " B, max=" + formatDecimal(mem.getMax()));
} catch (Exception e) {
log.error("Error in JMX memory stats retrieval", e);
}
}
private String formatDecimal(long value) {
return DECIMAL_FORMATTER.format(value);
}
@Override
public synchronized void start() {
super.start();
timeline.addValue(Timeline.Category.sysCategory(MEMORY_USAGE), new Timeline.Value(0));
}
@Override
public synchronized void stop() {
super.stop();
timeline.addValue(Timeline.Category.sysCategory(MEMORY_USAGE), new Timeline.Value(0));
}
}