堆 space 被 MemoryMXBean NotificationListener 占用
Heap space being taken up by MemoryMXBean NotificationListener
JMX 通知侦听器将使用多少内存?
我有一个 Java 7 的应用程序,它的最大堆很小。
我用一个 MemoryMXBean 通知侦听器监视它,但大部分堆都用完了。内存分析器报告:
One instance of "com.sun.jmx.remote.internal.ArrayNotificationBuffer"
loaded by "system class loader" occupies 16,810,416 (52.18%) bytes.
The instance is referenced by
sun.management.NotificationEmitterSupport$ListenerInfo @ 0xeda6d9e0 ,
loaded by "system class loader". The memory is accumulated in one
instance of "java.lang.Object[]" loaded by "system class loader".
我的代码
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);
当您创建内部 class 时,就像您代码中的 NotifcationListener 一样,class 会获得一个隐藏字段,该字段包含对创建实例的对象的引用。
您可以通过声明内部 class 静态
来修复内存泄漏
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());
JMX 通知侦听器将使用多少内存?
我有一个 Java 7 的应用程序,它的最大堆很小。
我用一个 MemoryMXBean 通知侦听器监视它,但大部分堆都用完了。内存分析器报告:
One instance of "com.sun.jmx.remote.internal.ArrayNotificationBuffer" loaded by "system class loader" occupies 16,810,416 (52.18%) bytes. The instance is referenced by sun.management.NotificationEmitterSupport$ListenerInfo @ 0xeda6d9e0 , loaded by "system class loader". The memory is accumulated in one instance of "java.lang.Object[]" loaded by "system class loader".
我的代码
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);
当您创建内部 class 时,就像您代码中的 NotifcationListener 一样,class 会获得一个隐藏字段,该字段包含对创建实例的对象的引用。
您可以通过声明内部 class 静态
来修复内存泄漏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());