排查Netty直接内存(Direct Memory)使用情况

结合Netty提供的PlatformDependent查看 Direct Memory 使用情况。

方法:通过 ​JMX 暴露 Netty 内存信息,再用 JConsole 查看

虽然 JConsole ​默认不显示 Netty 堆外内存,但你可以:

  1、在代码中通过 JMX 暴露 Netty 的堆外内存使用情况(比如使用 PlatformDependent.usedDirectMemory()的值)​​

  2、注册一个自定义的 MBean,将 usedDirectMemory 暴露出来​

  3、然后用 JConsole 连接,查看你自定义的 MBean 数据​

这样你就可以 ​间接但直观地在 JConsole 中看到 Netty 使用的堆外内存情况了。

实现步骤:

步骤

操作

目的

1

定义一个 MBean 接口:NettyMemoryMonitorMBean,含 getUsedDirectMemory()方法

定义要通过 JMX 暴露的属性

2

实现该接口:NettyMemoryMonitor,调用 PlatformDependent.usedDirectMemory()获取堆外内存字节数,并在构造函数中注册 MBean

实现逻辑并注册到 JMX

3

在应用启动时调用 NettyMemoryMonitor.getInstance(),触发 MBean 注册

确保 JMX 能发现该 Bean

4

使用 JConsole 连接你的 Java 进程,查看 com.example.monitor → NettyMemoryMonitor → UsedDirectMemory

实时查看 Netty 使用的堆外内存

 

1、创建接口
public interface NettyMemoryMonitorMBean {
    long getUsedDirectMemory();  // 单位是字节
}

2、创建实现类
import io.netty.util.internal.PlatformDependent;

import javax.management.MBeanServer;
import javax.management.ObjectName;
import java.lang.management.ManagementFactory;

public class NettyMemoryMonitor implements NettyMemoryMonitorMBean {

    private static final NettyMemoryMonitor INSTANCE = new NettyMemoryMonitor();

    // 私有构造
    private NettyMemoryMonitor() {
        registerMBean();
    }

    // 获取单例
    public static NettyMemoryMonitor getInstance() {
        return INSTANCE;
    }

    // 实现 MBean 接口方法
    @Override
    public long getUsedDirectMemory() {
        return PlatformDependent.usedDirectMemory(); // 返回当前 JVM 使用的 Direct Memory 字节数
    }

    // 将本 MBean 注册到 JVM 的 MBeanServer
    private void registerMBean() {
        try {
            MBeanServer mbs = ManagementFactory.getPlatformMBeanServer();
            ObjectName name = new ObjectName("com.example.monitor:type=NettyMemoryMonitor");
            if (!mbs.isRegistered(name)) {
                mbs.registerMBean(this, name);
                System.out.println("[NettyMemoryMonitor] 已注册 JMX MBean: com.example.monitor:type=NettyMemoryMonitor");
            } else {
                System.out.println("[NettyMemoryMonitor] MBean 已存在,无需重复注册");
            }
        } catch (Exception e) {
            System.err.println("[NettyMemoryMonitor] JMX MBean 注册失败: " + e.getMessage());
            e.printStackTrace();
        }
    }
}

3、定义Bean

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;

@Configuration
public class JmxConfig {
    @Bean
    public NettyMemoryMonitor nettyMemoryMonitor() {
        return NettyMemoryMonitor.getInstance(); // 触发注册
    }
}

启动服务后,获取PID,使用jconsole命令,打开窗口后选择对应的PID,进入监控页面。单位是字节,需要 ÷ (1024 * 1024) =**M 转为兆。

image

posted @ 2025-11-03 17:06  Commissar-Xia  阅读(13)  评论(0)    收藏  举报