1、问题
Tomcat服务器跑了一段时间后,发现Tomcat进程占用的CPU资源在80%-100%间,加上其它的进程,整个服务器的CPU处理100%运行状态。
2、通过process explorer查看Tomcat进程下的线程
process explorer下载:https://technet.microsoft.com/en-us/sysinternals/bb896653/
我使用的是汉化后的版本:https://files.cnblogs.com/files/shuilangyizu/processExplorer汉化版.zip
下载后直接打开就可以了。
点开tomcat进程:
这时候发现6596、12200两个TID线程占用CPU最高。
下面我们要找到这两个线程在我们程序中的位置。
3、通过jstack把进程下所以的Java线程栈的内容打印出文本中。
如我们的Tomcat进程PID为900。
jstack -l 7388 > c:/java.stack
注:通过tomcat的windows服务启动的tomcat是无法使用此命令获取线程栈的内容(如下图),必须通过startup.bat来启动。
4、分析stack文本
打开c:/java.stack文件。
通过process explorer获取到的线程TID对应的是stack文本线程栈描述内容中的nid的十进制值。
我们把TID为6596转成十六进制为19c4,然后根据19c4在stack文本中找到此线程栈的描述内容为:
根据描述,我们可以看到,此线程是处理到了SocketThread类的91行处。
91行代码是线程下的socket在阻塞状态下等待读取客户端发送过来的数据。
后面几个TID线程也是同样的问题。
5、解决
经分析+谷哥+度娘后,socket服务器每与一个客户连接都产生一条线程来处理事务的做法比较耗资源。
使用用NIO非阻塞的方式重写了socket后,问题得到解决。