服务器常见问题排查(一)——CPU 占用高、上下文频繁切换、频繁 GC
一般而言 cpu 异常往往还是比较好定位的。原因包括业务逻辑问题(死循环)、频繁 gc 以及上下文切换过多。而最常见的往往是业务逻辑(或者框架逻辑)导致的,可以使用 jstack 来分析对应的堆栈情况。
使用 jstack 排查占用率问题
当使用 jstack 排查占用率问题时,可以按照以下步骤进行:
首先,使用 top 命令找到占用率较高的进程,并记录其 PID。
接着,使用以下命令来查看该进程中占用 CPU 较高的线程:
该命令将显示进程中各个线程的 CPU 使用率,以及线程的 ID(TID)。3. 根据线程 ID(TID)获取 nid,可以使用以下命令:
这将把 TID 转换为 16 进制格式的 nid。4. 然后,通过以下命令来查看该线程的堆栈信息:
该命令将显示包含 nid 的堆栈信息。注意,这里使用了grep
命令来过滤输出结果,只显示包含 nid 的部分。-C5
表示在匹配项前后各显示 5 行上下文信息,--color
则用于在输出中添加颜色标记。5. 除了逐个查看线程的堆栈信息外,还可以对整个 jstack 文件进行分析。可以使用以下命令来统计各个状态的线程数量:
该命令将输出各个线程状态的数量,例如 RUNNABLE、BLOCKED、WAITING、TIMED_WAITING 等。如果 WAITING 或 TIMED_WAITING 的数量较多,那么可能存在一些问题。
通过以上步骤,我们可以使用 jstack 来定位占用率较高的问题,并进一步分析问题原因。
频繁 GC 问题
通过使用 jstat 工具的-gc 选项,我们可以观察 GC 的分代变化情况,以便确定 GC 是否过于频繁。具体来说,我们可以使用以下命令来观察进程的 GC 情况:
在上述命令中,<pid>
是目标 Java 进程的 PID,而1000
表示采样间隔(以毫秒为单位)。通过这个命令,我们可以获取关于 Survivor 区、Eden 区、老年代(Old Generation)、元数据区(Metaspace)的容量和使用量信息,以及关于 Young GC 和 Full GC 的耗时和次数以及总耗时信息。
具体来说,以下是一些关键指标的含义:
S0C/S1C 和 S0U/S1U:这两个指标分别表示 Survivor 0 区和 Survivor 1 区的容量和已使用的容量。如果这些值接近或达到其最大值,则可能需要进行 GC。
EC/EU:这两个指标分别表示 Eden 区的当前容量和已使用的容量。如果这些值接近或达到其最大值,则可能需要进行 GC。
OC/OU:这两个指标分别表示老年代的当前容量和已使用的容量。如果这些值接近或达到其最大值,则可能需要进行 GC。
MC/MU:这两个指标分别表示元数据区的当前容量和已使用的容量。如果这些值接近或达到其最大值,则可能需要进行 GC。
YGC/YGT:这两个指标分别表示 Young GC 的次数和所花费的总时间。如果这些值较高,则可能表明应用程序存在过多的短期对象引用,需要优化。
FGC/FGCT:这两个指标分别表示 Full GC 的次数和所花费的总时间。如果这些值较高,则可能表明应用程序存在过多的长期对象引用,需要优化。
GCT:这个指标表示应用程序进行 GC 的总时间。如果这个值较高,则可能表明应用程序需要进行优化以减少 GC 的开销。
通过观察这些指标,我们可以更好地了解 Java 进程的内存使用情况和垃圾回收情况。如果发现 GC 过于频繁或存在其他问题,我们可以进一步分析并采取相应的优化措施。
频繁上下文切换
上下文切换会消耗 CPU 的时间,并导致进程真正运行的时间缩短,从而成为系统性能下降的一个因素。过多的上下文切换可能会使得 CPU 花费过多的时间用于保存和恢复寄存器、内核栈以及虚拟内存等数据,从而影响系统的响应速度和吞吐量。
vmstat 是一个非常有用的系统性能分析工具,它可以提供关于系统内存、CPU 活动、分页和上下文切换等信息。
在使用 vmstat 查看上下文切换情况时,可以显示以下统计信息:
"cs"(上下文切换):显示系统每秒上下文切换的次数。自愿上下文切换(voluntary context switches)和非自愿上下文切换(non voluntary context switches)都会被计算在内。
"in"(中断):显示系统每秒中断的次数。这些中断可能来自硬件设备、网络或其他原因。
"r"(运行或可运行):显示正在运行或等待 CPU 的进程数。这个统计信息可以提供关于系统负载的总体视图。
"b"(阻塞):显示处于不可中断睡眠状态的进程数。这些进程通常是在等待某些资源(如 I/O 操作)可用。
需要注意的是,vmstat 命令的具体选项和输出可能会因操作系统和版本而有所不同。在使用 vmstat 时,建议查阅相关文档或使用"man vmstat"命令来获取特定系统上 vmstat 的详细使用说明和输出解释。
vmstat 是给出整个系统总体的上下文切换情况,要想查看每个进程的详细情况就需要使用 pidstat,加上-w 选项就可以查看进程上下文切换的情况 pidstat -w pid
命令,cswch 和 nvcswch 表示自愿及非自愿切换。
自愿上下文切换:进程无法获取所需的资源,导致的上下文切换,例如 IO、内存等资源不足时,就会发生自愿上下文切换
非自愿上下文切换:进程由于时间片已到等时间,被系统强制调度,进而发生的上下文切换,例如大量的进程都在争抢 CPU 时,就容易发生非自愿上下文切换
系统上下文切换的次数为多少时是不正常的呢?
系统上下文切换的次数是否正常,取决于系统本身的 CPU 性能。一般来说,如果系统的上下文切换次数比较稳定,在数百到一万以内,都应该算是正常的。然而,当上下文切换次数超过一万次,或者切换次数出现数量级的增长时,就可能已经出现了性能问题。
具体遇到问题的时候,需要根据变化的上下文切换类型,再做具体分析。例如:自愿上下文切换变多了,说明进程都在等待资源,有可能发生了 I/O 等其他问题;非自愿上下文切换变多了,说明进程都在被强制调度,也就是都在争抢 CPU,说明 CPU 的确成了瓶颈;中断次数变多了,说明 CPU 被中断处理程序占用,还需要通过查看/proc/interrupts 文件来分析具体的中断类型。
版权声明: 本文为 InfoQ 作者【遥遥知识库】的原创文章。
原文链接:【http://xie.infoq.cn/article/fe7fef3036ab411736e7f5c66】。文章转载请联系作者。
评论