持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第 9 天,点击查看活动详情
1 前言
我们都知道计算机操作系统各个组件之间的存取速度是差异很大的,在本文中将会从计算机的资源系统层面分析形成系统性能瓶颈的原因,接下来将会从 CPU、内存、IO 三个方面来分析查看。
2 CPU 层面
cpu,即计算机的中央处理器,围绕 cpu ,可以从以下三个方面来分析:
- 1 通过 top 命令,可以观测 cpu 的性能
- 2 通过 uptime 命令,可以查看 cpu 任务的派对情况
- 3 通过 vmstat 命令,可以查看 cpu 的繁忙程度
在操作系统中通过 top 命令,可以查看 cpu 的运行指标和详细性能,如果查看每个 cpu 的情况,则需要按 0 即可以查看每个 cpu 的运行情况。
如上图,一般关注 %cpu 的利用率以及系统的负载情况,即 load average。
系统的负载情况,除了 top 命令,也可以使用 uptime 来查看,负载展示的是最近 1min/5min/15min 的负载情况,load 的值/ cpu 的核心数,如果为 1 则代表系统已经达到极限,大于 1 则超负荷,小于 1 则代表系统还没有达到极限。
如何查看 cpu 的繁忙程度呢,可以通过 vmstat 进行查看,vmstat 命令之前没有讲述过,在这里说明一下参数的含义。
- r 代表等待执行的任务数,如果超出了 cpu 的个数即说明 cpu 资源达到了瓶颈
- b 等待 io 的线程数,此列的值代表读写磁盘的动作
- memory 代表系统的内存情况,swpd 代表正在使用的虚拟内存,单位为 k, free active 代表空闲和活跃的内存大小,inact 代表非活跃的内存大小
- si/so si 代表每秒交换区写入内存的大小,so 则是内存写入交换区的速度
- cs 代表每秒钟上下文切换的数量
3 内存层面
在计算机中,内存分为物理内存和虚拟内存,通过 top 命令,可以查看内存的使用情况。如上 top 命令结果所示, VIRT 代表的是虚拟内存,RES 代表的是进程实际占用的内存数量,SHR 代表的是共享内存的大小。
CPU 缓存的引入是因为内存和 cpu 之间巨大的读写速度的差异,解决的方法就是引入告诉缓存,这些缓存也会有很多层,越靠近 cpu 其读写速度越快,但是其容量就会减小。在 java 中,因为缓存行的存在,就引发了为伪共享的问题,在 jdk8 中,可以通过开启 -XX:-RestrictContended 参数并在对象上使用注解 @Contended 来避免伪共享的问题。通过 cat /proc/cpuinfo | grep cache 来查看缓存行的问题。
我们都知道,计算机操作数据的基本单位是页,页的大小一般为 4kb, 内存操作数据,也是通过映射表的方式来管理。在目前操作系统越来越大的时代,可以通过增加页尺寸的方式减少映射表来管理内存,这种页增大的技术称之为 Huge Page。
此外,还可以使用预先加载的方式来提升系统的性能,比如在 jdk 中,通过开启-XX:+AlwaysPreTouch 参数来实现,开启后 jvm 在启动的时候,就会把所有的内存进行预先分配,虽然会导致系统启动变慢,但是会提升系统运行时的性能。
4 IO 层面
IO 在计算机中是最慢的环节了,不仅仅是指的硬盘,还有一些外围设备,那么如何查看系统的 io 情况呢,可以通过 iostat 来进行查看:
如下图所示,可以查看系统的读写速度,用来评估系统的 io 繁忙情况。
硬盘操作是非常耗时的,以硬盘数据发生网络为例,在操作之前,需要将数据进行多次的缓冲区复制,还有多次内核空间和用户空间的切换,为了解决这个问题,有了零拷贝的技术,可以提升 io 的性能,比如 nginx 、netty、kafka 就是使用了该项技术提升了其读写速度。
5 总结
在本文中,从 cpu 、内存 和 io 三个层面来分析影响系统性能的因素,并提供了相应的查看命令和分析手段,在实际的工作中会有所帮助。