维护公司的一个项目, 运行在jvm 上的scala 语言编写; Akka Actor System 实现的一个web 系统。
问题: 项目启动后就能占用50% cpu 资源, 8核cpu的情况下, 由于刚启动没有任何负载, 占用cpu明显过多。
cpu 占用过多可能的几种情况:
- 一直在GC , gc overhead exceed limit
- 死循环,占用线程不释放
- 线程过多, 线程切换上下文开销大
由于项目刚启动就占用大cpu ,怀疑是项目中的定时任务初始化不当,将定时任务代码注销, 启动后cpu 占用没变,排除定时任务问题
通过jdk自带的分析工具,进行分析, 一般情况下我们都设置了环境变量,可以在命令行下直接使用, jdk自带了很多分析工具,在对应安装目录的bin路径下,可以自行搜索其用法。又由于该项目运行在jvm上,jvm具有跨平台的熟悉,所以直接在window下进行分析。Linux 下没有图形化界面,需要些额外设置。
打开cmd, 输入:jvisualvm
如图所示:左上角有可以分析的运行在jvm上的进程。可以看到也可以远程分析,需要额外的设置,对于我们这个问题,可以本地分析。
启动程序,重新开一个cmd, 我本地项目通过 java -jar xxx.war 启动,然后就可以在分析界面看到对应的xxx.war进程。如图所示
双击打开,可以看到,好多分析项, 有gc情况,cpu情况,线程数情况。
线程数接近500, 刚启动线程数接近500,线程数过高,可以向下翻动,发现很多线程都是在休眠状态,并没有得到执行。 同时可以检测没有死锁发生,不会线程占用cpu不释放。在到gc 面板看下gc频率。
通过上图分析,gc 频率正常。
综上,怀疑是项目初始化不当,导致线程数过多, 检查代码,发现项目初始化时,容器初始化过多, 一个容器初始化会有很多的守护线程,导致线程数过多,cpu占用过多。
项目使用的是akka actor system. 在项目中初始化了ActorSystem多次, 查阅资料,发现akka官网有对actorsystem 的说明:
多实例化的ActorSystem 也只实例化一次,重新编译,运行,发现线程数降下来了,cpu也降下来了。
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)