耗时20多秒的young gc,你见过吗?
开门见山↓,
图1
惊讶之余,我们一起探探究竟。
首先要会看gc log,一图胜千言↓
图2
有个细节很关键,user(用户耗时)+sys(系统耗时) <real(真实耗时)。
再来看下,每个耗时的具体口径↓
1、real time:GC事件整个过程自然流逝的绝对时间,这个跟钟表上的时间是一致的。(如果GC从10点开始,10点30结束,real time就是30分钟)。
2、user time:cpu花在用户态的时间。
3、sys time:cpu花在内核态的时间,也就是说内核发生系统调用所花费的时间。
大多数的young GC中,real time是小于sys+user time的,因为paralle垃圾回收器是多线程并发的去GC,所以user time是各个线程累积的一个时间,大概率要大于real time。
但是图1的case,是什么情况呢?有两种可能↓
1.CPU不够用
当cpu非常繁忙,进程和线程都比较多,写gc log的线程,抢不到cpu时间片的时候,real time显然就比sys+user时间长了。
可以用top命令来查看服务器的负载情况,如果cpu的使用率非常高,可以这样↓
(1)减少服务器上运行的进程数,让重要的进程可以获得足够的cpu资源。
(2)合理减少进程内的线程数,降低并行度。
(3)把应用部署到有足够cpu的服务器上。
2.IO压力大
应用做GC日志打印的时候,也需要访问磁盘。当磁盘的压力非常重的时候,GC事件就有可能被阻塞,这会导致real time变长。
注意:就算不是你的应用导致的磁盘负载重,如果服务器上其他的应用导致的磁盘压力也会导致real time变长。
可以用如下命令来监控服务器的磁盘负载情况:
sar -d -p 1
这个命令会输出每秒钟磁盘的读写数量。
如果你发现服务器的磁盘压力非常大,那么可以考虑下面的方法来解决:
(1)如果是我们的应用引起的,可以优化代码,减少不必要的io操作,也可以合并部分io操作,批量化。
(2)把应用部署到另一台磁盘负载不高的机器上。