记一次 JNI 导致 Java fd 泄露的排查过程

前几天接到反馈,线上某机器上的服务在进行后端调用的时候失败了。查看日志是端口分配失败。通过 netstat -nulp  看到大量端口占用,用户段端口49152 到 65535 全部被占满。于是通过 awk sort 和 uniq 统计出每个进程的端口占用情况,发现某些 Java 服务占用了 2w+ 端口,于是对该服务展开分析。

首先考虑的是应用有大量 Socket 对象没有关闭释放,于是将堆 dump 出来,使用 VisualVM 加载分析。由于泄露的是 UDP 端口,于是考虑查找 Java 中 UDP socket 对应的对象 DatagramSocket 。可是一顿操作之后发现堆中并不存在该类对象,倒是找到了几个 DatagramSocketAdaptor  对象。查看了框架发现使用了 Netty 做 NIO,因此实际使用的是 NioDatagramChannel 和 DatagramSocketAdaptor (更多…)