JMX通知监听器会耗尽多少内存?
我有一个带有小Max Heap的Java 7应用程序。
我使用单个MemoryMXBean通知侦听器监视它,并且大部分Heap都用完了。内存分析器报告:
" com.sun.jmx.remote.internal.ArrayNotificationBuffer"的一个实例 由"系统类加载器加载"占用16,810,416(52.18%)个字节。 该实例引用 sun.management.NotificationEmitterSupport $ ListenerInfo @ 0xeda6d9e0, 由"系统类加载器"加载。记忆累积在一个 " java.lang.Object []"的实例由"系统类加载器加载"。
我的代码
final MemoryMXBean mbean = ManagementFactory.newPlatformMXBeanProxy(mBeanServerConnection, MEMORY_MXBEAN_NAME, MemoryMXBean.class);
NotificationEmitter emitter = (NotificationEmitter) mbean;
emitter.addNotificationListener(new NotificationListener() {
@Override
public void handleNotification(Notification notification, Object handback) {
if (notification.getType().equals(MemoryNotificationInfo.MEMORY_THRESHOLD_EXCEEDED)) {
LOG.info("Memory threshold exceeded !!!");
}
if (notification.getType().equals(MemoryNotificationInfo.MEMORY_COLLECTION_THRESHOLD_EXCEEDED)) {
LOG.error("Memory Collection threshold exceeded !!!");
}
}
}, null, null);
答案 0 :(得分:2)
当您在代码中创建内部类(如NotifcationListener)时,该类将获取一个隐藏字段,该字段包含对创建实例的对象的引用。
您可以通过声明内部类静态来修复内存泄漏,
static class LogListener implements NotifciationListener {
@Override
public void handleNotification(Notification notification, Object handback) {
LOG.info("Notification!");
}
}
然后创建一个像这样的实例
MemoryMXBean mbean = ManagementFactory.newPlatformMXBeanProxy(mBeanServerConnection,
MEMORY_MXBEAN_NAME, MemoryMXBean.class);
NotificationEmitter emitter = (NotificationEmitter) mbean;
emitter.addNotificationListener(new LogListener());