原文在这里: GC日志中sys时间比user时间长该如何处理?
GC日志中会详细的记录每一次GC事件所花费的时间信息,每一个GC事件所花费的时间都会以’user’、‘sys’、'real’3个维度来记录,这3个时间是什么意思呢?他们之间有什么区别?
1.real time:GC事件整个过程自然流逝的绝对时间,这个跟钟表上的时间是一致的。(ps:如果GC从8点开始,8点30结束,real time就是30分钟)。
2.user time:cpu花在用户态的时间
3.sys time:cpu花在内核态的时间,也就是说内核发生系统调用所花费的时间,不包括调用lib库的时间,因为这是发生在用户态。
一般来说,GC事件中user time是大于sys time的,因为在发生GC的时候,大部分时间是在执行JVM的代码,只有很少的时间用在内核中。但是,有时候是会发生sys time比user time长的场景。
比如:
[Times: user=0.04 sys=0.35, real=0.42 secs]
上例中,sys time是0.35秒,这个要远大于user time的0.04秒。
如果在你的GC日志中经常有这样的日志,那你很有可能遇到了以下问题:
1.操作系统的问题
操作系统出现诸如缺页、未对齐的内存引用、浮点数异常这样的问题的时候就会花费大量的sys time,要确保你的操作系统打好了补丁,升级了最新版本,有足够的cpu、内存、磁盘空间。
2.虚拟机相关问题
如果你的应用是运行在虚拟化环境中,可能会出现sys time比user time长,要确保虚拟化环境不因为环境多而过载,同时要确保给运行你应用的虚拟机分配了足够的资源。
3.内存限制
在linux系统上,JVM和操作系统都可能会申请大的内存页(比如2M/页),如果操作系统找不到连续的空闲内存来分配2M的页,那它就会把所有运行的进程全都暂停掉,然后整理内存以找到连续的空闲内存。如果操作系统是在做这个事情,那么sys time就会比real time还要大。如果出现了这种情况,要么就给机器分配足够的内存,要么就减少机器上运行的进程数量。
4.磁盘IO的压力
JVM会把安全点和GC事件的统计信息写到/tmp/hsperfdata_(username) 文件中,当发生GC的时候就会更新这个文件。当磁盘的IO负载比较高的时候,内核线程可能会阻塞GC线程更新这个文件。因此如果磁盘的IO负载非常重的话是有可能增加GC的停顿时间的。如果发生了这种情况,要么real time远大于sys time+user time,要么sys time远大于user time。此时,就需要降低磁盘的IO负载才可以。可以用lsof来查看磁盘的IO负载情况。
英文原文:https://blog.gceasy.io/2016/12/11/sys-time-greater-than-user-time/
如果感觉有用欢迎扫描文章开头的二维码加关注。