写点什么

服务器常见问题排查(一)——CPU 占用高、上下文频繁切换、频繁 GC

作者:遥遥知识库
  • 2023-10-26
    北京
  • 本文字数:2360 字

    阅读完需:约 8 分钟

服务器常见问题排查(一)——CPU占用高、上下文频繁切换、频繁GC

一般而言 cpu 异常往往还是比较好定位的。原因包括业务逻辑问题(死循环)、频繁 gc 以及上下文切换过多。而最常见的往往是业务逻辑(或者框架逻辑)导致的,可以使用 jstack 来分析对应的堆栈情况。

使用 jstack 排查占用率问题

当使用 jstack 排查占用率问题时,可以按照以下步骤进行:


  1. 首先,使用 top 命令找到占用率较高的进程,并记录其 PID。

  2. 接着,使用以下命令来查看该进程中占用 CPU 较高的线程:


top -H -p <pid>
复制代码


该命令将显示进程中各个线程的 CPU 使用率,以及线程的 ID(TID)。3. 根据线程 ID(TID)获取 nid,可以使用以下命令:


printf '%x\n' <tid>
复制代码


这将把 TID 转换为 16 进制格式的 nid。4. 然后,通过以下命令来查看该线程的堆栈信息:


jstack <pid> | grep 'nid' -C5 --color
复制代码



该命令将显示包含 nid 的堆栈信息。注意,这里使用了grep命令来过滤输出结果,只显示包含 nid 的部分。-C5表示在匹配项前后各显示 5 行上下文信息,--color则用于在输出中添加颜色标记。5. 除了逐个查看线程的堆栈信息外,还可以对整个 jstack 文件进行分析。可以使用以下命令来统计各个状态的线程数量:


cat jstack.log | grep "java.lang.Thread.State" | sort -nr | uniq -c
复制代码


该命令将输出各个线程状态的数量,例如 RUNNABLE、BLOCKED、WAITING、TIMED_WAITING 等。如果 WAITING 或 TIMED_WAITING 的数量较多,那么可能存在一些问题。


通过以上步骤,我们可以使用 jstack 来定位占用率较高的问题,并进一步分析问题原因。

频繁 GC 问题

通过使用 jstat 工具的-gc 选项,我们可以观察 GC 的分代变化情况,以便确定 GC 是否过于频繁。具体来说,我们可以使用以下命令来观察进程的 GC 情况:


jstat -gc <pid> 1000
复制代码


在上述命令中,<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 查看上下文切换情况时,可以显示以下统计信息:



  1. "cs"(上下文切换):显示系统每秒上下文切换的次数。自愿上下文切换(voluntary context switches)和非自愿上下文切换(non voluntary context switches)都会被计算在内。

  2. "in"(中断):显示系统每秒中断的次数。这些中断可能来自硬件设备、网络或其他原因。

  3. "r"(运行或可运行):显示正在运行或等待 CPU 的进程数。这个统计信息可以提供关于系统负载的总体视图。

  4. "b"(阻塞):显示处于不可中断睡眠状态的进程数。这些进程通常是在等待某些资源(如 I/O 操作)可用。


需要注意的是,vmstat 命令的具体选项和输出可能会因操作系统和版本而有所不同。在使用 vmstat 时,建议查阅相关文档或使用"man vmstat"命令来获取特定系统上 vmstat 的详细使用说明和输出解释。


vmstat 是给出整个系统总体的上下文切换情况,要想查看每个进程的详细情况就需要使用 pidstat,加上-w 选项就可以查看进程上下文切换的情况 pidstat -w pid命令,cswch 和 nvcswch 表示自愿及非自愿切换。



cswch(voluntary context switches):表示每秒自愿上下文切换的次数nvcswch(non voluntary context switches):表示每秒非自愿上下文切换的次数
复制代码


  1. 自愿上下文切换:进程无法获取所需的资源,导致的上下文切换,例如 IO、内存等资源不足时,就会发生自愿上下文切换

  2. 非自愿上下文切换:进程由于时间片已到等时间,被系统强制调度,进而发生的上下文切换,例如大量的进程都在争抢 CPU 时,就容易发生非自愿上下文切换


系统上下文切换的次数为多少时是不正常的呢?


系统上下文切换的次数是否正常,取决于系统本身的 CPU 性能。一般来说,如果系统的上下文切换次数比较稳定,在数百到一万以内,都应该算是正常的。然而,当上下文切换次数超过一万次,或者切换次数出现数量级的增长时,就可能已经出现了性能问题。


具体遇到问题的时候,需要根据变化的上下文切换类型,再做具体分析。例如:自愿上下文切换变多了,说明进程都在等待资源,有可能发生了 I/O 等其他问题;非自愿上下文切换变多了,说明进程都在被强制调度,也就是都在争抢 CPU,说明 CPU 的确成了瓶颈;中断次数变多了,说明 CPU 被中断处理程序占用,还需要通过查看/proc/interrupts 文件来分析具体的中断类型。

发布于: 刚刚阅读数: 3
用户头像

欢迎访问 yaoyaolx.wiki ~ 2020-02-14 加入

微信公众号和同名网站:遥遥知识库

评论

发布
暂无评论
服务器常见问题排查(一)——CPU占用高、上下文频繁切换、频繁GC_后端_遥遥知识库_InfoQ写作社区