ScheduledExecutorService 一个小坑

今天在排查一个线上问题是发现一个使用 ScheduledExecutorService 执行的定时任务在执行了一次以后就再也没有执行过了。于是 Dump 了内存来检查问题。

首先,搜索对应 Task 的类,发现在堆中找不到这个类的实例。可是明明已经成功执行了一次,为何没有实例?

于是再去找 ScheduledExecutorService  对应的 ScheduledThreadPoolExecutor  类,成功筛选出了用来执行定时任务的实例。在实例的 queue 中,却只看到了 6 个 Task 对象,唯独不见了这个出问题的对象。百思不得解,因为日志中这个对象的 Logger 已经打印出来了,说明至少执行了一次,为啥会从内存中消失呢?

在同事的帮助下,查阅了 API 文档,发现了这么一句话:

If any execution of the task encounters (更多…)

记一次 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 (更多…)