排查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 接口: |
定义要通过 JMX 暴露的属性 |
|
2 |
实现该接口: |
实现逻辑并注册到 JMX |
|
3 |
在应用启动时调用 |
确保 JMX 能发现该 Bean |
|
4 |
使用 JConsole 连接你的 Java 进程,查看 |
实时查看 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 转为兆。


浙公网安备 33010602011771号