https://juejin.cn/post/7340920192995966986
前几天下午飞书告警群里报起了java.lang.OutOfMemoryError: unable to create new native thread告警,看见后艾特了对应的项目负责人但是负责人说没时间,无奈自己亲自上阵。
从报错信息就可以看出是服务申请不到足够的内存去创建新的线程导致的,熟悉JVM的都知道线程用的是虚拟机栈内存,这里是虚拟机栈内存不够跟堆没有关系。
然后立马登录阿里云进入容器使用如下命令dump出线程堆栈
jstack -l 1 > dump.log
让运维帮我把文件下载下来后,就把dump.log上传到网站fastthread.io/进行分析,分析结果如下:
可以看到服务的线程数竟然高达2000多个!!!而且也给出来警告这么高的线程数可能导致OOM,那么问题原因就很清楚了就是线程数过多导致的,那么是哪些线程过多呢?
第二张图显示数量做多的是名字为com.alibaba.nacos.client.Worker的线程,并且排行前三名都是nacos的线程,我一度怀疑是nacos出bug了🤣🤣🤣
再点进去看看对应的线程堆栈如下图:
可以看出线程阻塞在从队列获取任务那里,说明这些线程都是没活干,空闲挂起的,具体看不出问题原因,只能看代码了。
打开项目,使用idea全局搜索com.alibaba.nacos.client.Worker,发现是ClientWorker类在构造方法里创建了一个定时线程池,线程名称就叫com.alibaba.nacos.client.Worker,其中核心线程数是4。
继续跟踪源码,发现只有在NacosConfigService的构造方法里调用了ClientWorke的构造方法。