本文是关于Jedis的socket内存泄露问题排查的分享。
背景
业务线上有N台机器。其中有一台会缓慢的出现Socket内存泄露。具体表现为在jmap时会常常看到如下类排名很靠前。
5: 274623 30757776 java.net.SocksSocketImpl
8: 274621 13181808 java.net.SocketInputStream
9: 274621 13181808 java.net.SocketOutputStream
17: 274621 8787872 java.net.Socket
21: 274668 6592032 java.net.Inet4Address
从占用数量以及内存情况来说。其实完全是可以接受的。但是不能理解的是为什么就单独这台机器占用偏高。其他机器也有一定的数量,但是和这台机器差别较多。
STEP0
这一台机器唯一和别的机器不同的是:
该机器周期性的在本机进程内执行一些数据逻辑。每5分钟调度一次,每次大概执行1分多钟。所以相比其他机器,他的YGC相对会频繁一点。大约10秒左右触发一次。而其他机器大概是1分钟触发一次。
STEP1
既然创建了这么多的socket相关对象。那需要看看是谁在不停的创建。这里可以使用开源的btrace或者其他instrument工具进行运行时监控(PS: 如果对于instrument和agent感兴趣的可以看此文如何开发一款java应用运行时的监控程序https://juejin.im/entry/5bd7f9156fb9a05d185f3a