centos7释放下缓存 centos7内存占用过高_centos7释放下缓存


前段时间我们遇到了dubbo无权限写本地注册文件引起的CPU 100%问题,最终排查结果是由一个死循环引起。作为后端开发攻城狮,日常开发时不时会遇到一些CPU使用率异常的问题,那么针对这些情况怎么排查?


centos7释放下缓存 centos7内存占用过高_centos7释放下缓存_02


一、常见能够引起CPU100%异常的情况都有哪些?

1. Java 内存不够或者溢出导致GC overhead limit exceeded。 2. 代码中互相竞争导致的死锁。 3. 特别耗费计算资源的操作,比如正则匹配,Java中的正则匹配默认有回溯问题,复杂的正则匹配引起的CPU异常。 4.

针对第1种,根据Oracle官方资料,GC overhead limit exceeded表示JVM一直在GC导致应用程序变慢,具体量化指标就是JVM执行垃圾回收花费超过98%的时间,但释放出的可用堆内存却少于2%,连续多次(一般5次)GC回收的内存都不足2%的情况下就会抛出此异常。

经过垃圾回收每次释放的内存都少于2%很容易又被新生对象填满,JVM快速进入下一次垃圾回收,无限循环,由此引起频繁的GC长期消耗我们服务器CPU资源,从而使CPU使用率达到100%

我们可以使用-XX:-UseGCOverheadLimit这个参数关闭GC overhead limit exceeded,但这样治标不治本,建议检查应用程序的内存使用是否合理以及是否需要增加堆内存。

二、服务器CPU使用率飙升异常,黄金4步排查法

1. TOP命令找到占用CPU高的Java进程PID

top


centos7释放下缓存 centos7内存占用过高_垃圾回收_03


2. 根据进程ID找到占用CPU高的线程

ps -mp pid -o THREAD,tid | sort -r


centos7释放下缓存 centos7内存占用过高_垃圾回收_04


3. 将指定的线程ID输出为16进制格式

printf "%xn" tid


centos7释放下缓存 centos7内存占用过高_centos7释放下缓存_05


4. 根据16进制格式的线程ID查找线程堆栈信息

jstack pid |grep tid -A 50


centos7释放下缓存 centos7内存占用过高_Java_06


获取到线程堆栈信息就好办了,以上即是采用单线程模拟一个复杂的正则匹配的堆栈示例图,可以看得出线程都在指向regex.Pattern,在生产多线程环境下这个复杂正则匹配会导致CPU利用率齐高。

总结、提升
做一个积极快乐的人
构筑属于自己的一方天地