java gc cpucpu 100%,怀疑是GC的时候出的问题,求教高手

Java项目服务器cpu占用100%解决办法 -
- ITeye技术网站
博客分类:
项目上线后运行一段时间,突然发现cpu 8个逻辑核心都占用100%,心情很紧张,然后就在网上找了一些解决方法,具体如下:
1.查找哪些进程在耗cpu
进入服务器,top 命令看一下,发现进程6633占用了800%
[root@3server ~]# top
2.把进程的栈dump到文件里,以便后面的分析
[root@3server ~]# jstack 6633 & cpu1128.log
3.看看这个进程里面哪些线程在占用cpu
[root@3server ~]# top -p 6633 -H
一大片占用cpu很高的线程,选一个最高的吧,PID=5159
4.接着要看刚才dump出来的cpu日志了,里面会有6633这个进程下面每个线程的栈信息,但是是十六进制显示的,所以先把5159转换成16进制
[root@3server ~]# printf %0x 5159
[root@3server ~]# 1427
5.在cpu日志里找PID=1427的线程
[root@3server ~]# vi cpu1128.log
6.分析原因
看日志,很明显是org.hibernate.exception.ExceptionUtils.getCauseUsingWellKnowTypes(...)这里“卡住”了。这个线程是"RUNABLE"状态的,难道在这里发生了死循环?后来花了很多时间在debug状态下把这个问题重现了(Hibernate 3.3.1.GA版本,通过hessian调用远程服务器报SQLGrammarException异常,就会出现这个问题)。跟踪到hibernate源码里发现了问题:
public static int getThrowableCount(Throwable throwable) {
int count = 0;
while ( throwable != null ) {
throwable = ExceptionUtils.getCause( throwable );
这个方法里,throwable和它的cause引用的同一个SQLGrammarException对象,导致在while这里产生了死循环。这肯定是hibernate的bug了。于是把hibernate升级到3.3.2.GA(原来是3.3.1.GA,不敢升太多)问题解决。
此用户被哥注册
浏览: 1266 次
来自: 杭州记一次线上Java程序导致服务器CPU占用率过高的问题排除过程 - 简书
记一次线上Java程序导致服务器CPU占用率过高的问题排除过程
1、故障现象
客服同事反馈平台系统运行缓慢,网页卡顿严重,多次重启系统后问题依然存在,使用top命令查看服务器情况,发现CPU占用率过高。
2、CPU占用过高问题定位
2.1、定位问题进程
使用top命令查看资源占用情况,发现pid为14063的进程占用了大量的CPU资源,CPU占用率高达776.1%,内存占用率也达到了29.8%
[ylp@ylp-web-01 ~]$ top
top - 14:51:10 up 233 days, 11:40,
load average: 6.85, 5.62, 3.97
Tasks: 192 total,
2 running, 190 sleeping,
0 stopped,
%Cpu(s): 97.3 us,
5114392 free,
6907028 used,
4247232 buff/cache
4063228 total,
3989708 free,
73520 used.
8751512 avail Mem
TIME+ COMMAND
11976 S 776.1 29.8 117:41.66 java
2.2、定位问题线程
使用ps -mp pid -o THREAD,tid,time命令查看该进程的线程情况,发现该进程的多个线程占用率很高
[ylp@ylp-web-01 ~]$ ps -mp 14063 -o THREAD,tid,time
%CPU PRI SCNT WCHAN
USER SYSTEM
- 02:05:58
从输出信息可以看出,之间的线程CPU占用率都很高
2.3、查看问题线程堆栈
挑选TID为14065的线程,查看该线程的堆栈情况,先将线程id转为16进制,使用printf "%x\n" tid命令进行转换
[ylp@ylp-web-01 ~]$ printf "%x\n" 14065
再使用jstack命令打印线程堆栈信息,命令格式:jstack pid |grep tid -A 30
[ylp@ylp-web-01 ~]$ jstack 14063 |grep 36f1 -A 30
"GC task thread#0 (ParallelGC)" prio=10 tid=0x0e800 nid=0x36f1 runnable
"GC task thread#1 (ParallelGC)" prio=10 tid=0x0800 nid=0x36f2 runnable
"GC task thread#2 (ParallelGC)" prio=10 tid=0x0800 nid=0x36f3 runnable
"GC task thread#3 (ParallelGC)" prio=10 tid=0x0000 nid=0x36f4 runnable
"GC task thread#4 (ParallelGC)" prio=10 tid=0x0000 nid=0x36f5 runnable
"GC task thread#5 (ParallelGC)" prio=10 tid=0x0000 nid=0x36f6 runnable
"GC task thread#6 (ParallelGC)" prio=10 tid=0x0800 nid=0x36f7 runnable
"GC task thread#7 (ParallelGC)" prio=10 tid=0x0b800 nid=0x36f8 runnable
"VM Periodic Task Thread" prio=10 tid=0x0a8800 nid=0x3700 waiting on condition
JNI global references: 392
从输出信息可以看出,此线程是JVM的gc线程。此时可以基本确定是内存不足或内存泄露导致gc线程持续运行,导致CPU占用过高。所以接下来我们要找的内存方面的问题
3、内存问题定位
3.1、使用jstat -gcutil命令查看进程的内存情况
[ylp@ylp-web-01 ~]$ jstat -gcutil
0.00 100.00
0.00 100.00
0.00 100.00
0.00 100.00
0.00 100.00
0.00 100.00
0.00 100.00
0.00 100.00
0.00 100.00
0.00 100.00
从输出信息可以看出,Eden区内存占用100%,Old区内存占用99.99%,Full GC的次数高达220次,并且频繁Full GC,Full GC的持续时间也特别长,平均每次Full GC耗时6.8秒()。根据这些信息,基本可以确定是程序代码上出现了问题,可能存在不合理创建对象的地方
3.2、分析堆栈
使用jstack命令查看进程的堆栈情况
[ylp@ylp-web-01 ~]$ jstack 14063 &&jstack.out
把jstack.out文件从服务器拿到本地后,用编辑器查找带有项目目录并且线程状态是RUNABLE的相关信息,从图中可以看出ActivityUtil.java类的447行正在使用HashMap.put()方法
Paste_Image.png
3.3、代码定位
打开项目工程,找到ActivityUtil类的477行,代码如下:
Paste_Image.png
找到相关同事了解后,这段代码会从数据库中获取配置,并根据数据库中remain的值进行循环,在循环中会一直对HashMap进行put操作。
查询数据库中的配置,发现remain的数量巨大
Paste_Image.png
至此,问题定位完毕。

我要回帖

更多关于 java gc cpu 的文章

 

随机推荐