使用file-leak-detector指定为应用程序的javaagent,然后重启程序,通过file-leak-detector提供能力,可以查看句柄和线程名称的信息,可直接排查出是哪行代码问题
包下载地址:http://search.maven.org/remotecontent?filepath=org/kohsuke/file-leak-detector/1.13/file-leak-detector-1.13-jar-with-dependencies.jar
git地址:https://github.com/jenkinsci/lib-file-leak-detector
两种方式,必须是在同一台机器
和项目一起启动
#查看入参解释
java -javaagent:/data/file-leak-detector.jar=http=19999,trace=/data/tracefile.log -jar project.jar
直接启动,并将要监控的jvm虚拟机PID指定为入参
java -jar path/to/file-leak-detector-jar-with-dependencies.jar PID http=19999
http=19999,trace=/data/tracefile.log
如果生产环境19999端口未开放,可以使用curl命令查看句柄信息
#查看全部句柄信息
curl localhost:19999
#只看每个句柄的第一行
curl localhost:19999 | grep "by thread:"
#查看每个句柄的前两行和首行
curl localhost:19999 | grep -A 2 "by thread:"
#其他命令
curl localhost:19999 | grep "socket channel by" | wc -l
curl localhost:19999 | grep "selector by" | wc -l
curl localhost:19999 | grep "selector by\|socket channel by"
#样例
#4 selector by thread:Kafka-LagCheck1 on Tue Jan 09 11:24:01 CST 2024
at java.nio.channels.spi.AbstractSelector.<init>(AbstractSelector.java:86)
at sun.nio.ch.SelectorImpl.<init>(SelectorImpl.java:54)
at sun.nio.ch.EPollSelectorImpl.<init>(EPollSelectorImpl.java:64)
at sun.nio.ch.EPollSelectorProvider.openSelector(EPollSelectorProvider.java:36)
at java.nio.channels.Selector.open(Selector.java:227)
at org.apache.kafka.common.network.Selector.<init>(Selector.java:160)
at org.apache.kafka.common.network.Selector.<init>(Selector.java:214)
at org.apache.kafka.common.network.Selector.<init>(Selector.java:227)
at org.apache.kafka.common.network.Selector.<init>(Selector.java:231)
at org.apache.kafka.clients.consumer.KafkaConsumer.<init>(KafkaConsumer.java:749)
at org.apache.kafka.clients.consumer.KafkaConsumer.<init>(KafkaConsumer.java:666)
at org.apache.kafka.clients.consumer.KafkaConsumer.<init>(KafkaConsumer.java:646)
#查看句柄数详情
lsof -p PID
#统计某个PID句柄数
lsof -p PID|wc -l