Linux性能分析 – 内存篇

Linux 内核给每个进程都提供了一个独立的虚拟地址空间,并且这个地址空间是连续的。这样,进程就可以很方便地访问内存,更确切地说是访问虚拟内存。虚拟地址空间的内部又被分为内核空间和用户空间两部分,不同字长(也就是单个 CPU 指令可以处理数据的最大长度)的处理器,地址空间的范围也不同。

注意不同版本的 free 输出可能会有所不同

xwq@xwq:~$ free -h
              总计         已用        空闲      共享    缓冲/缓存    可用
内存:        7.8G        1.2G        3.5G         12M        3.1G        6.3G
交换:        2.0G          0B        2.0G

第一列,total 是总内存大小;
第二列,used 是已使用内存的大小,包含了共享内存;
第三列,free 是未使用内存的大小;
第四列,shared 是共享内存的大小;
第五列,buff/cache 是缓存和缓冲区的大小;
最后一列,available 是新进程可用内存的大小。

Buffers 是对原始磁盘块的临时存储,也就是用来缓存磁盘的数据,通常不会特别大(20MB 左右)。这样,内核就可以把分散的写集中起来,统一优化磁盘的写入,比如可以把多次小的写合并成单次大的写等等。
Cached 是从磁盘读取文件的页缓存,也就是用来缓存从文件读取的数据。这样,下次访问这些文件数据时,就可以直接从内存中快速获取,而不需要再次访问缓慢的磁盘。
SReclaimable 是 Slab 的一部分。Slab 包括两部分,其中的可回收部分,用SReclaimable 记录;而不可回收部分,用 SUnreclaim 记录。

清理文件页、目录项、Inodes 等各种缓存

$ echo 3 > /proc/sys/vm/drop_caches

Buffer 是对磁盘数据的缓存,而 Cache 是文件数据的缓存,它们既会用在读请求中,也会用在写请求中。

缓存命中率
命中率越高,表示使用缓存带来的收益越高,应用程序的性能也就越好。
cachestat 提供了整个操作系统缓存的读写命中情况。
cachetop 提供了每个进程的缓存命中情况。
需要安装bcc软件包才有上面的这两个工具

 sudo apt-key adv --keyserver keyserver.ubuntu.com --recv-keys 4052245BD4284CDD
    echo "deb https://repo.iovisor.org/apt/xenial xenial main" | sudo tee /etc/apt/sources.list
    sudo apt-get update
    sudo apt-get install -y bcc-tools libbcc-examples linux-headers-$(uname -r)
    手动配置bcc软件包路径到系统PATH路径
    $ export PATH=$PATH:/usr/share/bcc/tools

    cachestat的运行界面,它以 1 秒的时间间隔,输出了 3 组缓存统计数据
    root@xwq:~# cachestat 1 3
        HITS   MISSES  DIRTIES HITRATIO   BUFFERS_MB  CACHED_MB
           0        0        0    0.00%          111       1451
           2        0        0  100.00%          111       1451
           0        0        0    0.00%          111       1451

这些指标从左到右依次表示:
TOTAL ,表示总的 I/O 次数;
MISSES ,表示缓存未命中的次数;
HITS ,表示缓存命中的次数;
DIRTIES, 表示新增到缓存中的脏页数;
BUFFERS_MB 表示 Buffers 的大小,以 MB 为单位;
CACHED_MB 表示 Cache 的大小,以 MB 为单位。

$ cachetop
09:48:20 Buffers MB: 111 / Cached MB: 1452 / Sort: HITS / Order: ascending
PID      UID      CMD HITS     MISSES   DIRTIES  READ_HIT%  WRITE_HIT%
    2149 root     cachetop                1        0        0     100.0%       0.0%
     295 root     jbd2/sda1-8             5        5        3      20.0%      20.0%

它的输出跟 top 类似,默认按照缓存的命中次数(HITS)排序,展示了每个进程的缓存命中情况。具体到每一个指标,这里的 HITS、MISSES 和 DIRTIES ,跟 cachestat 里的含义一样,分别代表间隔时间内的缓存命中次数、未命中次数以及新增到缓存中的脏页数。而 READ_HIT 和 WRITE_HIT ,分别表示读和写的缓存命中率。

专门用来检测内存泄漏的工具,memleak。memleak 可以跟踪系统或指定进程的内存分配、释放请求,然后定期输出一个未释放内存和相应调用栈的汇总情况(默认 5 秒)。memleak 是 bcc 软件包中的一个工具,我们一开始就装好了,执行/usr/share/bcc/tools/memleak 就可以运行它

# -a 表示显示每个内存分配请求的大小以及地址
# -p 指定案例应用的 PID 号
/usr/share/bcc/tools/memleak -a -p $(pidof app)

sar 命令,查看内存各个指标的变化情况

# -r 表示显示内存使用情况,-S 表示显示 Swap 使用情况
$ sar -r -S 1
10时49分34秒 kbmemfree   kbavail kbmemused  %memused kbbuffers  kbcached  kbcommit   %commit  kbactive   kbinact   kbdirty
10时49分35秒    225744   5554372   7918516     97.23   5100040    330176   5949040     58.09   1737476   5625308         0

10时49分34秒 kbswpfree kbswpused  %swpused  kbswpcad   %swpcad
10时49分35秒   2091004      6144      0.29       200      3.26

sar 的输出结果是两个表格,第一个表格表示内存的使用情况,第二个表格表示 Swap 的使用情况。其中,各个指标名称前面的 kb 前缀,表示这些指标的单位是KB。

  • kbcommit,表示当前系统负载需要的内存。它实际上是为了保证系统内存不溢出,对需要内存的估计值。%commit,就是这个值相对总内存的百分比。
  • kbactive,表示活跃内存,也就是最近使用过的内存,一般不会被系统回收。
  • kbinact,表示非活跃内存,也就是不常访问的内存,有可能会被系统回收。

快速定位内存问题

  • 已用内存和剩余内存很容易理解,就是已经使用和还未使用的内存。
  • 共享内存是通过 tmpfs 实现的,所以它的大小也就是 tmpfs 使用的内存大小。tmpfs其实也是一种特殊的缓存。
  • 可用内存是新进程可以使用的最大内存,它包括剩余内存和可回收缓存。
  • 缓存包括两部分,一部分是磁盘读取文件的页缓存,用来缓存从磁盘读取的数据,可以加快以后再次访问的速度。另一部分,则是 Slab 分配器中的可回收内存。
  • 缓冲区是对原始磁盘块的临时存储,用来缓存将要写入磁盘的数据。这样,内核就可以把分散的写集中起来,统一优化磁盘写入。
  • 虚拟内存,包括了进程代码段、数据段、共享内存、已经申请的堆内存和已经换出的内存等。这里要注意,已经申请的内存,即使还没有分配物理内存,也算作虚拟内存。
  • 常驻内存是进程实际使用的物理内存,不过,它不包括 Swap 和共享内存。
  • 共享内存,既包括与其他进程共同使用的真实的共享内存,还包括了加载的动态链接库以及程序的代码段等。
  • Swap 内存,是指通过 Swap 换出到磁盘的内存

缺页异常:可以直接从物理内存中分配时,被称为次缺页异常。需要磁盘 I/O 介入(比如 Swap)时,被称为主缺页异常。主缺页异常升高,就意味着需要磁盘 I/O,那么内存访问也会慢很多。


快速定位内存性能问题分析思路

  1. 先用 free 和 top,查看系统整体的内存使用情况。
  2. 再用 vmstat 和 pidstat,查看一段时间的趋势,从而判断出内存问题的类型。
  3. 最后进行详细分析,比如内存分配分析、缓存 / 缓冲区分析、具体进程的内存使用分析
    等。

|| 版权声明
作者:废权
链接:https://blog.yjscloud.com/archives/117
声明:如无特别声明本文即为原创文章仅代表个人观点,版权归《废权的博客》所有,欢迎转载,转载请保留原文链接。
THE END
分享
二维码
Linux性能分析 – 内存篇
Linux 内核给每个进程都提供了一个独立的虚拟地址空间,并且这个地址空间是连续的。这样,进程就可以很方便地访问内存,更确切地说是访问虚拟内存。虚拟地址空……
<<上一篇
下一篇>>
文章目录
关闭
目 录