原因及解决办法:一是病毒所致。下载安装杀毒软件,对硬盘特别是系统盘进行反复查杀,彻底查杀隐藏在系统中的各种病毒。并在今后使用电安,安装各种应用软件前做好查杀病毒事项,防止病毒再次入侵。二是运行项目过多,特别是运行大型游戏时,导致cpu压力过大,导致难以运行甚至死机,这种情况下我们要关闭不必要的程序,减轻cpu的压力。三是系统垃圾过多。日常使用过程中,要保持良好的用机习惯,经常对系统盘进行垃圾清理,保证系统正常运行。

2、第二步 执行top -Hp 1,查看到进程1下面的pid是8,9,10,11这四个线程的cpu占用比较异常

对应java程序里的tid是0x8 0x9 0xa 0xb。

3、第三步执行jstack 1 > 20191107.log 获取到日志文件,查到刚好是垃圾回收的几个线程

4、第四步再执行jstat -gcutil 1 2000

发现FGC很频繁,而且有没次fgc的效率不高,就算回收了还是暂用97、98%,说明有大量的老年代对象没有被回收

5、第五步,是什么原因导致老年代对象没有被回收呢,首先我们先执行java -XX:+PrintCommandLineFlags -version

newRatio 等于2,老年代,占比2/3,4/3g * 98% = 1.306g的老年代堆内存一直不能被回收。

6、第六步,执行jmap -dump:format=b,file=20191029.dump 1,生成dump文件,使用visualVm工具打开dump文件

分析发现有很多boundSql占用了大量的内存,并且不能被释放,这条sql是updateBatchById,查询数据库

这条sql一直被占用,并且不会被释放。查阅代码,发现有一条批量更新语句,使用case id when then 的语法,这条批量更新语句更新大概2w行数据,导致数据库SQL语句执行缓慢,e其实是固定的,没有必要这样写sql。后修改SQL 为updat a set a.c = d where e = xxx,重新部署,运行一段时间,服务器的cpu一直正常。