性能优化---内存分析工具详解

性能优化 —- 内存相关工具详解

sar -B 命令

sar -B命令用于报告page相关的系统活动,我们来依次看一下每项输出的具体含义

pgpgin/s:系统每秒从磁盘读取到内存页的数据大小(kb)

我们可以读取一个系统的大文件,这样就能观测到此值的增加.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
$ cat 1.txt  # 1.txt是我创建的一个大文件

# sar -B 1
Linux 5.11.0-44-generic (zhangxa-VirtualBox) 2022年01月16日 _x86_64_ (2 CPU)

09时38分16秒 pgpgin/s pgpgout/s fault/s majflt/s pgfree/s pgscank/s pgscand/s pgsteal/s %vmeff

09时38分47秒 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00 0.00
09时38分48秒 1336.00 0.00 146.00 1.00 144.00 0.00 0.00 0.00 0.00
09时38分49秒 3072.00 0.00 0.00 0.00 184.00 0.00 0.00 0.00 0.00
09时38分50秒 3840.00 0.00 0.00 0.00 273.00 0.00 0.00 0.00 0.00
09时38分51秒 4096.00 0.00 0.00 0.00 520.00 0.00 0.00 0.00 0.00
09时38分52秒 3840.00 0.00 0.00 0.00 305.00 0.00 0.00 0.00 0.00
09时38分53秒 4096.00 12.00 0.00 0.00 248.00 0.00 0.00 0.00 0.00
09时38分54秒 3072.00 0.00 0.00 0.00 224.00 0.00 0.00 0.00 0.00
09时38分55秒 1024.00 0.00 0.00 0.00 73.00 0.00 0.00 0.00 0.00
09时38分56秒 1536.00 0.00 0.00 0.00 80.00 0.00 0.00 0.00 0.00

pgpgout/s:系统每秒从内存页写入到磁盘的数据大小(kb)

这一项和pgpgin正好相反,我们可以循环写一个大文件,这里要注意,我们需要手工调用sync,以便能触发立即写入磁盘.

1
2
3
4
5
6
7
8
$ while [ 1 = 1 ] ; do echo "hello the worldaaaaaaaaa1111111111111111" >> ./1.txt; sync; done

# sar -B 1
Linux 5.11.0-44-generic (zhangxa-VirtualBox) 2022年01月16日 _x86_64_ (2 CPU)

09时42分00秒 pgpgin/s pgpgout/s fault/s majflt/s pgfree/s pgscank/s pgscand/s pgsteal/s %vmeff
09时42分01秒 0.00 12488.00 84738.00 0.00 54856.00 0.00 0.00 0.00 0.00
09时42分02秒 0.00 12144.00 81464.00 0.00 52669.00 0.00 0.00 0.00 0.00

fault/s:系统中未命中page fault的次数

majflt和minflt都会引起这个值增长

其中minflt增长的一般原因有:
一种是文件系统cache未命中,需要从磁盘中读取.我们可以通过不断执行sync操作来模拟.
另一种可能是进程需要进行物理内存的实际分配映射,我们可以写一个程序频繁申请内存来模拟.

majflt增长的原因通常是物理页面在磁盘中或者需要淘汰部分页到磁盘中,一般物理内存不足时会发生这种情况.

模拟内存申请程序:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
#include <unistd.h>

#include <stdio.h>
#include <stdlib.h>

#define MALLOC_NUM 10000
int main() {
char *p[MALLOC_NUM];
while(1) {
for (int i = 0; i < MALLOC_NUM; i++) {
p[i] = malloc(130*1024);
}

sleep(1);

for (int i = 0; i < MALLOC_NUM; i++) {
free(p[i]);
}
}

return 0;
}

运行程序可以看到此值不断增长

1
2
3
4
5
6
7
8
# sar -B 1
Linux 5.11.0-44-generic (zhangxa-VirtualBox) 2022年01月16日 _x86_64_ (2 CPU)

11时45分27秒 pgpgin/s pgpgout/s fault/s majflt/s pgfree/s pgscank/s pgscand/s pgsteal/s %vmeff
11时45分28秒 0.00 0.00 10008.00 0.00 10658.00 0.00 0.00 0.00 0.00
11时45分29秒 0.00 0.00 10000.00 0.00 10655.00 0.00 0.00 0.00 0.00
11时45分30秒 0.00 0.00 9999.00 0.00 10654.00 0.00 0.00 0.00 0.00
11时45分31秒 0.00 172.00 9999.00 0.00 10655.00 0.00 0.00 0.00 0.0

pgfree/s:系统每秒回收的空闲内存页,当内存页空闲可以再次分配时此值会增加

我们可以通过执行sync操作看到此值的增长.

pgscank/s pgscand/s:后台kswapd进程或直接扫描过的页面,此值过高说明当前内存紧张,在频繁的扫描寻找可用内存页.

linux在内存紧张时后回收可能的内存页使用,回收操作可能由kswapd进程周期性地进行也可能在内存分配等相关路径上进行,如果pgscand/s过高
一般就说明当前内存很紧张了,而pagscank/s过高有可能时当前有较多的页释放了(如文件系统缓存),也有可能是内存紧张.