You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为JMX中Memory MBean的HeapMemoryUsage内的committed属性添加监听器?

正确监听HeapMemoryUsage中committed属性变化的方法

你之前的代码报错,核心问题是把CompositeData的子属性当成了独立的MBean——HeapMemoryUsage是java.lang:type=Memory这个标准MXBean的一个属性,并非一个单独的MBean实例,所以java.lang:type=Memory,name=HeapMemoryUsage.committed这个ObjectName对应的MBean根本不存在,自然会抛出InstanceNotFoundException。

要监听committed属性的变化,你需要监听原Memory MBean的HeapMemoryUsage属性,然后在监听器中解析CompositeData,提取committed的值。具体有两种常用方式:

方式一:使用AttributeChangeNotificationListener(推荐)

这种方式直接利用JMX的属性变化通知机制,监听HeapMemoryUsage属性的变化,再从中提取committed值:

// 获取MBean服务器连接
MBeanServerConnection connection = jmxConnector.getMBeanServerConnection();
ObjectName memoryMBeanName = new ObjectName("java.lang:type=Memory");

// 创建属性变化监听器
AttributeChangeNotificationListener committedListener = (notification, handback) -> {
    // 确认是属性变化通知
    if (AttributeChangeNotification.ATTRIBUTE_CHANGE.equals(notification.getType())) {
        AttributeChangeNotification attrNotify = (AttributeChangeNotification) notification;
        // 过滤出HeapMemoryUsage属性的变化
        if ("HeapMemoryUsage".equals(attrNotify.getAttributeName())) {
            CompositeData newHeapUsage = (CompositeData) attrNotify.getNewValue();
            Long newCommittedValue = (Long) newHeapUsage.get("committed");
            // 这里处理committed值的变化逻辑
            System.out.println("Heap committed memory updated to: " + newCommittedValue + " bytes");
        }
    }
};

// 注册监听器,同时添加过滤器只接收HeapMemoryUsage的变化通知
connection.addNotificationListener(
    memoryMBeanName,
    committedListener,
    // 通知过滤器:只保留HeapMemoryUsage的属性变化通知
    notification -> {
        if (notification instanceof AttributeChangeNotification) {
            AttributeChangeNotification acn = (AttributeChangeNotification) notification;
            return "HeapMemoryUsage".equals(acn.getAttributeName());
        }
        return false;
    },
    null // 可选的回传对象,这里不需要
);

关键说明:

  • 我们监听的还是java.lang:type=Memory这个真实存在的MBean。
  • HeapMemoryUsage作为CompositeData类型的属性,当内存使用情况变化时,JMX会发送AttributeChangeNotification。
  • 通过过滤器可以减少不必要的通知处理,只关注我们关心的属性。

方式二:自定义通知转发(复杂场景可选)

如果你的业务需要更细粒度的监听(比如只在committed值真正变化时触发逻辑),可以自己封装一个小逻辑,在监听器中对比前后committed的值:

// 保存上一次的committed值,用于对比
private Long lastCommittedValue;

// 在监听器中添加对比逻辑
AttributeChangeNotificationListener committedListener = (notification, handback) -> {
    if (AttributeChangeNotification.ATTRIBUTE_CHANGE.equals(notification.getType())) {
        AttributeChangeNotification attrNotify = (AttributeChangeNotification) notification;
        if ("HeapMemoryUsage".equals(attrNotify.getAttributeName())) {
            CompositeData newHeapUsage = (CompositeData) attrNotify.getNewValue();
            Long currentCommitted = (Long) newHeapUsage.get("committed");
            // 只有当值真正变化时才处理
            if (lastCommittedValue == null || !lastCommittedValue.equals(currentCommitted)) {
                System.out.println("Heap committed memory changed: " + lastCommittedValue + " -> " + currentCommitted);
                lastCommittedValue = currentCommitted;
            }
        }
    }
};

这种方式可以避免因为CompositeData对象本身引用变化但committed值未变时触发不必要的逻辑。

内容的提问来源于stack exchange,提问作者Carla

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.27 17:54:06