package org.toobs.framework.management;
import java.lang.management.ManagementFactory;
import java.lang.management.MemoryMXBean;
import java.lang.management.MemoryNotificationInfo;
import java.lang.management.MemoryPoolMXBean;
import java.lang.management.MemoryUsage;
import java.util.HashMap;
import java.util.Map;
import javax.management.Notification;
import javax.management.NotificationBroadcaster;
import javax.management.NotificationListener;
import javax.management.openmbean.CompositeData;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
public class MemoryMonitor {
private static Log log = LogFactory.getLog(MemoryMonitor.class);
private static final Map<String, MemoryPoolMXBean> memPools = new HashMap<String, MemoryPoolMXBean>();
private static MemoryMonitor instance;
private MemoryMonitor() {
init();
}
public static MemoryMonitor getInstance() {
if (instance == null) {
instance = new MemoryMonitor();
}
return instance;
}
private static final NotificationListener listener = new NotificationListener() {
public void handleNotification(Notification notification, Object handback) {
if (MemoryNotificationInfo.MEMORY_THRESHOLD_EXCEEDED.equals(notification.getType())) {
CompositeData cd = (CompositeData)notification.getUserData();
MemoryNotificationInfo info = MemoryNotificationInfo.from(cd);
MemoryUsage memUsage = info.getUsage();
String poolName = info.getPoolName();
System.out.printf("Notification: %s, count=%d, usage=[%s]%n",
poolName,
info.getCount(),
memUsage);
MemoryPoolMXBean memPool = memPools.get(poolName);
setUsageThreshold(memPool, 0.85);
}
}
};
public static void setUsageThreshold(MemoryPoolMXBean memPool, double percentage) {
MemoryUsage memUsage = memPool.getUsage();
long max = memUsage.getMax();
memPool.setUsageThreshold((long)(max * percentage));
}
private void init() {
MemoryMXBean mem = ManagementFactory.getMemoryMXBean();
((NotificationBroadcaster)mem).addNotificationListener(listener, null, null);
for (MemoryPoolMXBean memPool : ManagementFactory.getMemoryPoolMXBeans()) {
if (memPool.isUsageThresholdSupported()) {
memPools.put(memPool.getName(), memPool);
log.info("Putting Pool " + memPool.getName());
setUsageThreshold(memPool, 0.7);
}
}
}
}