cpu高的怎么回事(三)

2021-07-20  本文已影响0人  勤_

概述

接着上篇cpu高的怎么回事(二),通过一些实例继续分析性能问题的现象和原因,希望能给研发兄弟们一点点参考价值。

工具及版本

工具 版本
Arthas 3.5.2
perf 3.10.0-1160.31.1.el7.x86_64.debug
JDK 1.8.0_221

实例

通过代码来模拟下CPU切换的情况。这种情况下CPU又是怎样的一种表象?先了解下概念:

进程在竞争CPU的时候并没有真正运行,是CPU上下文切换导致平均负载升高。在每个任务运行前,CPU都需要知道任务从哪里加载、又从哪里开始运行,也就是说,需要系统事先帮他设置好CPU寄存器程序计数器

cpu寄存器是CPU内置的容量小、但速度极快的内存。而程序计数器,则是 用来存储CPU正在执行的指令位置、或者即将执行的下一条指令位置。他们都是CPU在运行任何任务前,必须的依赖环境,因此也被叫做CPU上下文

CPU上下文切换,就是先把前一个任务的CPU上下文(也就是CPU寄存器和程序计数器)保存起来,然后加载新任务的上下文到这些寄存器和程序计数器,最后再跳转到程序计数器所指的新位置,运行新任务。而这些保存下来的上下文,会存储在系统内核中,并在任务重新调度之行时候再次加载进来,这样就能保证任务原来的状态不受影响,让任务看起来还是连续运行。

根据任务的不同,cpu的上在问切换可以分为几个不同的场景,也就是进程上下文切换、线程上下文切换、中断上下文切换。

Linux按照特权等级,把进程的运行空间分为内核空间和用户空间,分别对应下图中的Ring 0和Ring 3。

内核空间(Ring 0)具有最高权限,可以直接访问所有资源。

用户空间(Ring 3)只能访问受限资源,不能直接访问内存等硬件设备,必须通过系统调用陷入到内核中,才能访问这些特权资源。

也就是说,进程既可以在用户空间运行,又可以在内核空间中运行。进程在用户空间运行时候,被称为进程 的用户态,而陷入内核空间的时候,被称为进程的内核态。

从用户态到内核态的转变,需要通过系统调用来完成。例如,当我们查看文件内容时候,就需要多次系统调用来完成:首先调用open()打开文件,然后调用read()读取文件内容,并调用write()将内容写出到标准输出,最后再调用close()关闭文件。系统调用的过程也需要CPU进行上下文切换。

CPU寄存器里原来用户态的指令位置,需要先保存起来。接着,为了执行内核状态代码,cpu寄存器需要更新为内核态指令的新位置,最后才是跳转到内核态运行内核任务。系统调用结束后,CPU寄存器需要恢复原来保存的用户态,然后再切换到用户空间,继续运行进程。所以,一次系统调用的过程,其实时发生了两次CPU上下文切换。

好了,接下来主要是演示线程上下文切换。

CPU切换

1,先用java代码实现一个多线程切换的例子,并部署到服务器上,并触发cpu切换的场景。这是查看下cpu的使用情况,如下图所示

image-20210719172214333.png

当然你也可以不用写这些例子,直接使用stress\sysbench等工具运行压测,从而深刻了解CPU上下文切换的现象。

sudo yum install -y epel-release
sudo yum install -y stress
stress -c 2 --timeout 600
yum install -y sysbench
sysbench --threads=10 --max-time=600 threads run

2,使用vmstat、pidstat、perf、pstree分析下,看看我们能发现点什么现象。

3,接下来使用top+jstack\Arthas分析下。

参考

cpu高的怎么回事(一)

cpu高的怎么回事(二)

cpu高的怎么回事(三)

Arthas 安装

pidstat

上一篇 下一篇

猜你喜欢

热点阅读