Linux对机器进行性能分析之内存篇

前言

前面我们已经学习了 CPU 篇,这篇来看下内存篇。

内存信息

/proc/meminfo

这个文件记录着比较详细的内存配置信息,使用 cat /proc/meminfo 查看。

[root@master ~]# cat /proc/meminfo
MemTotal:        1863196 kB
系统总内存,由于 BIOS、内核等会占用一些内存,所以这里和配置声称的内存会有一些出入,比如我这里配置有 2G,但其实只有 1.51G 可用。

MemFree:          121916 kB
系统空闲内存。

MemAvailable:     551240 kB
应用程序可用内存。有人会比较奇怪和 MemFree 的区别,可以从两个层面来区分,MemFree 是系统层面的,而 MemAvailable 是应用程序层面的。系统中有些内存虽然被使用了但是有一部分是可以回收的,比如 Buffers、Cached 及 Slab 这些内存,这部分可以回收的内存加上 MemFree 才是 MemAvailable 的内存值,这是内核通过特定算法算出来的,是一个估算值。

Buffers:             204 kB
缓冲区内存

Cached:           539568 kB
缓存

SwapCached:            0 kB
Active:           955436 kB
Inactive:         367568 kB
Active(anon):     761336 kB
Inactive(anon):    36160 kB
Active(file):     194100 kB
Inactive(file):   331408 kB
Unevictable:           0 kB
Mlocked:               0 kB
SwapTotal:       2097148 kB
SwapFree:        2097148 kB
Dirty:                 4 kB
Writeback:             0 kB
AnonPages:        783228 kB
Mapped:           134288 kB
Shmem:             14264 kB
Slab:             127384 kB
SReclaimable:      69812 kB
SUnreclaim:        57572 kB
KernelStack:       11040 kB
PageTables:        42224 kB
NFS_Unstable:          0 kB
Bounce:                0 kB
WritebackTmp:          0 kB
CommitLimit:     3028744 kB
Committed_AS:    4617028 kB
VmallocTotal:   34359738367 kB
VmallocUsed:      185664 kB
VmallocChunk:   34359310332 kB
HardwareCorrupted:     0 kB
AnonHugePages:    122880 kB
CmaTotal:              0 kB
CmaFree:               0 kB
HugePages_Total:       0
HugePages_Free:        0
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:       2048 kB
DirectMap4k:      141184 kB
DirectMap2M:     1955840 kB
DirectMap1G:           0 kB

上面信息没有 MemUsed 的值,虽然可以用现有的值大致估算出来,但是我们想一步到位,就用下面的 free 命令。

free

这个命令估计用的人就多了(我一般都是用这个命令)。
在这里插入图片描述这里存在一个计算公式:

MemTotal = used + free + buff/cache(单位 K)

几个字段和上面 /proc/meminfo 的字段是对应的。还有个 shared 字段,这个是多进程的共享内存空间,不常用。

我们注意到 free 很小,buff/cache 却很大,这是 Linux 的内存设计决定的,Linux 的想法是内存闲着反正也是闲着,不如拿出来做系统缓存和缓冲区,提高数据读写的速率。但是当系统内存不足时,buff/cache 会让出部分来,非常灵活的操作。

要看比较直观的值,可以加 -h 参数
在这里插入图片描述

dmidecode

同样可以使用这个命令,对于内存,可以使用 dmidecode -t memory 查看:

[root@master ~]# dmidecode -t memory |grep Size
	Maximum Memory Module Size: 32768 MB
	Maximum Total Memory Size: 491520 MB
	Installed Size: 2048 MB (Single-bank Connection)
	Enabled Size: 2048 MB (Single-bank Connection)
	Installed Size: Not Installed

Maximum Memory Module Size: 32768 MB,Maximum Total Memory Size: 491520 MB怎么这么大,这是做什么用的?

vmstat

这个命令也是非常常用了。但对于内存,显示信息有限。它更多是用于进行系统全局分析和 CPU 分析。详细可以看 CPU 分析一文。

进程内存使用情况分析

最常用的两个命令 ps 和 top,虽然很简单的两个命令,但还是有不少学问的。
top 命令运行时默认是按照 CPU 利用率进行排序的,如果要按照内存排序,该怎么操作呢?两种方法,一种直接按 “M”(相应的按 “P” 是 CPU),另外一种是在键入 top 之后,按下 “F”,然后选择要排序的字段,再按下 “s” 确认即可。
在这里插入图片描述可以看到,我按照 “%MEM” 排序的结果。这个结果对于查看系统占用内存较多的哪些进程是比较有用的。

然后这里我们会重点关注几个地方,上面横排区,和前面几个命令一样可以查看系统内存信息,中间标注的横条部分,和内存相关的有三个字段:VIRT、RES、SHR。

  • VIRT:virtual memory usage,进程占用的虚拟内存大小。
  • RES:resident memory usage,进程常驻内存大小,也就是实际内存占用情况,一般我们看进程占用了多少内存,就是看的这个值。
  • SHR:shared memory,共享内存大小,不常用。

ps

ps 同样可以查看进程占用内存情况,一般常用来查看 Top n 进程占用内存情况,如:
ps aux --sort=rss | head -n,表示按 rss 排序,取 Top n。

[root@master ~]# ps aux --sort=vsz | head -10
USER        PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root          2  0.0  0.0      0     0 ?        S    09:59   0:00 [kthreadd]
root          3  0.0  0.0      0     0 ?        S    09:59   0:00 [ksoftirqd/0]
root          5  0.0  0.0      0     0 ?        S<   09:59   0:00 [kworker/0:0H]
root          7  0.0  0.0      0     0 ?        S    09:59   0:00 [migration/0]
root          8  0.0  0.0      0     0 ?        S    09:59   0:00 [rcu_bh]
root          9  0.0  0.0      0     0 ?        R    09:59   0:03 [rcu_sched]
root         10  0.0  0.0      0     0 ?        S<   09:59   0:00 [lru-add-drain]
root         11  0.0  0.0      0     0 ?        S    09:59   0:00 [watchdog/0]
root         13  0.0  0.0      0     0 ?        S    09:59   0:00 [kdevtmpfs]

这里也关注三个字段:

  • %MEM:进程使用物理内存所占百分比。
  • VSZ:进程使用虚拟内存大小。
  • RSS:进程使用物理内存大小,我们会重点关注这个值。

pmap

这个命令用于查看进程的内存映像信息,能够查看进程在哪些地方用了多少内存。 常用 pmap -x pid 来查看。

[root@master ~]# pmap -x 7501
7501:   /usr/sbin/sshd -D
Address           Kbytes     RSS   Dirty Mode  Mapping
0000563423750000     800     284       0 r-x-- sshd
0000563423a17000      16      16      16 r---- sshd
0000563423a1b000       4       4       4 rw--- sshd
0000563423a1c000      36      36      36 rw---   [ anon ]
0000563423fba000     132      60      60 rw---   [ anon ]
00007f600838e000      48      20       0 r-x-- libnss_files-2.17.so
00007f600839a000    2044       0       0 ----- libnss_files-2.17.so
00007f6008599000       4       4       4 r---- libnss_files-2.17.so
00007f600859a000       4       4       4 rw--- libnss_files-2.17.so
00007f600859b000      24       0       0 rw---   [ anon ]
00007f60085a1000      60       8       0 r-x-- libbz2.so.1.0.6
00007f60085b0000    2044       0       0 ----- libbz2.so.1.0.6
00007f60087af000       4       4       4 r---- libbz2.so.1.0.6
00007f60087b0000       4       4       4 rw--- libbz2.so.1.0.6
00007f60087b1000      92      16       0 r-x-- libelf-0.172.so
00007f60087c8000    2044       0       0 ----- libelf-0.172.so
00007f60089c7000       4       4       4 r---- libelf-0.172.so
00007f60089c8000       4       4       4 rw--- libelf-0.172.so
00007f60089c9000      16       8       0 r-x-- libattr.so.1.1.0
00007f60089cd000    2044       0       0 ----- libattr.so.1.1.0
00007f6008bcc000       4       4       4 r---- libattr.so.1.1.0
00007f6008bcd000       4       4       4 rw--- libattr.so.1.1.0
00007f6008bce000      12       8       0 r-x-- libkeyutils.so.1.5
00007f6008bd1000    2044       0       0 ----- libkeyutils.so.1.5
00007f6008dd0000       4       4       4 r---- libkeyutils.so.1.5
00007f6008dd1000       4       4       4 rw--- libkeyutils.so.1.5
00007f6008dd2000      52      16       0 r-x-- libkrb5support.so.0.1
00007f6008ddf000    2048       0       0 ----- libkrb5support.so.0.1
00007f6008fdf000       4       4       4 r---- libkrb5support.so.0.1
00007f6008fe0000       4       4       4 rw--- libkrb5support.so.0.1
00007f6008fe1000       8       4       0 r-x-- libfreebl3.so
00007f6008fe3000    2044       0       0 ----- libfreebl3.so
00007f60091e2000       4       4       4 r---- libfreebl3.so
00007f60091e3000       4       4       4 rw--- libfreebl3.so
00007f60091e4000     232      52       0 r-x-- libnspr4.so
00007f600921e000    2044       0       0 ----- libnspr4.so
00007f600941d000       4       4       4 r---- libnspr4.so
00007f600941e000       8       8       8 rw--- libnspr4.so
00007f6009420000       8       0       0 rw---   [ anon ]
00007f6009422000      16       8       0 r-x-- libplc4.so
00007f6009426000    2044       0       0 ----- libplc4.so
00007f6009625000       4       4       4 r---- libplc4.so
00007f6009626000       4       4       4 rw--- libplc4.so
00007f6009627000      12       4       0 r-x-- libplds4.so
00007f600962a000    2044       0       0 ----- libplds4.so
00007f6009829000       4       4       4 r---- libplds4.so
00007f600982a000       4       4       4 rw--- libplds4.so
00007f600982b000     160      52       0 r-x-- libnssutil3.so
00007f6009853000    2044       0       0 ----- libnssutil3.so
00007f6009a52000      28      28      28 r---- libnssutil3.so
00007f6009a59000       4       4       4 rw--- libnssutil3.so
00007f6009a5a000    1168     100       0 r-x-- libnss3.so
00007f6009b7e000    2048       0       0 ----- libnss3.so
00007f6009d7e000      20      20      20 r---- libnss3.so
00007f6009d83000       8       8       8 rw--- libnss3.so
00007f6009d85000       8       0       0 rw---   [ anon ]
00007f6009d87000     144      40       0 r-x-- libsmime3.so
00007f6009dab000    2044       0       0 ----- libsmime3.so
00007f6009faa000      12      12      12 r---- libsmime3.so
00007f6009fad000       4       4       4 rw--- libsmime3.so
00007f6009fae000     308      52       0 r-x-- libssl3.so
00007f6009ffb000    2044       0       0 ----- libssl3.so
00007f600a1fa000      16      16      16 r---- libssl3.so
00007f600a1fe000       4       4       4 rw--- libssl3.so
00007f600a1ff000       4       0       0 rw---   [ anon ]
00007f600a200000     412     104       0 r-x-- libssl.so.1.0.2k
00007f600a267000    2048       0       0 ----- libssl.so.1.0.2k
00007f600a467000      16      16      16 r---- libssl.so.1.0.2k
00007f600a46b000      28      28      28 rw--- libssl.so.1.0.2k
00007f600a472000     112      20       0 r-x-- libsasl2.so.3.0.0
00007f600a48e000    2044       0       0 ----- libsasl2.so.3.0.0
00007f600a68d000       4       4       4 r---- libsasl2.so.3.0.0
00007f600a68e000       4       4       4 rw--- libsasl2.so.3.0.0
00007f600a68f000      92      60       0 r-x-- libpthread-2.17.so
00007f600a6a6000    2044       0       0 ----- libpthread-2.17.so
00007f600a8a5000       4       4       4 r---- libpthread-2.17.so
00007f600a8a6000       4       4       4 rw--- libpthread-2.17.so
00007f600a8a7000      16       4       4 rw---   [ anon ]
00007f600a8ab000      84      12       0 r-x-- libgcc_s-4.8.5-20150702.so.1
00007f600a8c0000    2044       0       0 ----- libgcc_s-4.8.5-20150702.so.1
00007f600aabf000       4       4       4 r---- libgcc_s-4.8.5-20150702.so.1
00007f600aac0000       4       4       4 rw--- libgcc_s-4.8.5-20150702.so.1
00007f600aac1000     304      52       0 r-x-- libdw-0.172.so
00007f600ab0d000    2048       0       0 ----- libdw-0.172.so
00007f600ad0d000       8       8       8 r---- libdw-0.172.so
00007f600ad0f000       4       4       4 rw--- libdw-0.172.so
00007f600ad10000      16       8       0 r-x-- libgpg-error.so.0.10.0
00007f600ad14000    2044       0       0 ----- libgpg-error.so.0.10.0
00007f600af13000       4       4       4 r---- libgpg-error.so.0.10.0
00007f600af14000       4       4       4 rw--- libgpg-error.so.0.10.0
00007f600af15000     500      36       0 r-x-- libgcrypt.so.11.8.2
00007f600af92000    2044       0       0 ----- libgcrypt.so.11.8.2
00007f600b191000       4       4       4 r---- libgcrypt.so.11.8.2
00007f600b192000      12      12      12 rw--- libgcrypt.so.11.8.2
00007f600b195000       4       0       0 rw---   [ anon ]
00007f600b196000      80      12       0 r-x-- liblz4.so.1.7.5
00007f600b1aa000    2044       0       0 ----- liblz4.so.1.7.5
00007f600b3a9000       4       4       4 r---- liblz4.so.1.7.5
00007f600b3aa000       4       4       4 rw--- liblz4.so.1.7.5
00007f600b3ab000     148      16       0 r-x-- liblzma.so.5.2.2
00007f600b3d0000    2044       0       0 ----- liblzma.so.5.2.2
00007f600b5cf000       4       4       4 r---- liblzma.so.5.2.2
00007f600b5d0000       4       4       4 rw--- liblzma.so.5.2.2
00007f600b5d1000      28      16       0 r-x-- librt-2.17.so
00007f600b5d8000    2044       0       0 ----- librt-2.17.so
00007f600b7d7000       4       4       4 r---- librt-2.17.so
00007f600b7d8000       4       4       4 rw--- librt-2.17.so
00007f600b7d9000    1028      64       0 r-x-- libm-2.17.so
00007f600b8da000    2044       0       0 ----- libm-2.17.so
00007f600bad9000       4       4       4 r---- libm-2.17.so
00007f600bada000       4       4       4 rw--- libm-2.17.so
00007f600badb000      16       8       0 r-x-- libcap.so.2.22
00007f600badf000    2044       0       0 ----- libcap.so.2.22
00007f600bcde000       4       4       4 r---- libcap.so.2.22
00007f600bcdf000       4       4       4 rw--- libcap.so.2.22
00007f600bce0000     384       8       0 r-x-- libpcre.so.1.2.0
00007f600bd40000    2048       0       0 ----- libpcre.so.1.2.0
00007f600bf40000       4       4       4 r---- libpcre.so.1.2.0
00007f600bf41000       4       4       4 rw--- libpcre.so.1.2.0
00007f600bf42000      16       8       0 r-x-- libcap-ng.so.0.0.0
00007f600bf46000    2048       0       0 ----- libcap-ng.so.0.0.0
00007f600c146000       4       4       4 r---- libcap-ng.so.0.0.0
00007f600c147000       4       4       4 rw--- libcap-ng.so.0.0.0
00007f600c148000      88      20       0 r-x-- libnsl-2.17.so
00007f600c15e000    2048       0       0 ----- libnsl-2.17.so
00007f600c35e000       4       4       4 r---- libnsl-2.17.so
00007f600c35f000       4       4       4 rw--- libnsl-2.17.so
00007f600c360000       8       0       0 rw---   [ anon ]
00007f600c362000    1800     680       0 r-x-- libc-2.17.so
00007f600c524000    2048       0       0 ----- libc-2.17.so
00007f600c724000      16      16      16 r---- libc-2.17.so
00007f600c728000       8       8       8 rw--- libc-2.17.so
00007f600c72a000      20      20      20 rw---   [ anon ]
00007f600c72f000      12       8       0 r-x-- libcom_err.so.2.1
00007f600c732000    2044       0       0 ----- libcom_err.so.2.1
00007f600c931000       4       4       4 r---- libcom_err.so.2.1
00007f600c932000       4       4       4 rw--- libcom_err.so.2.1
00007f600c933000     100      24       0 r-x-- libk5crypto.so.3.1
00007f600c94c000    2044       0       0 ----- libk5crypto.so.3.1
00007f600cb4b000       8       8       8 r---- libk5crypto.so.3.1
00007f600cb4d000       4       4       4 rw--- libk5crypto.so.3.1
00007f600cb4e000     868     148       0 r-x-- libkrb5.so.3.3
00007f600cc27000    2044       0       0 ----- libkrb5.so.3.3
00007f600ce26000      56      56      56 r---- libkrb5.so.3.3
00007f600ce34000      12      12      12 rw--- libkrb5.so.3.3
00007f600ce37000     296      48       0 r-x-- libgssapi_krb5.so.2.2
00007f600ce81000    2048       0       0 ----- libgssapi_krb5.so.2.2
00007f600d081000       4       4       4 r---- libgssapi_krb5.so.2.2
00007f600d082000       8       8       8 rw--- libgssapi_krb5.so.2.2
00007f600d084000      88      16       0 r-x-- libresolv-2.17.so
00007f600d09a000    2044       0       0 ----- libresolv-2.17.so
00007f600d299000       4       4       4 r---- libresolv-2.17.so
00007f600d29a000       4       4       4 rw--- libresolv-2.17.so
00007f600d29b000       8       0       0 rw---   [ anon ]
00007f600d29d000      32       4       0 r-x-- libcrypt-2.17.so
00007f600d2a5000    2044       0       0 ----- libcrypt-2.17.so
00007f600d4a4000       4       4       4 r---- libcrypt-2.17.so
00007f600d4a5000       4       4       4 rw--- libcrypt-2.17.so
00007f600d4a6000     184       0       0 rw---   [ anon ]
00007f600d4d4000      84      12       0 r-x-- libz.so.1.2.7
00007f600d4e9000    2044       0       0 ----- libz.so.1.2.7
00007f600d6e8000       4       4       4 r---- libz.so.1.2.7
00007f600d6e9000       4       4       4 rw--- libz.so.1.2.7
00007f600d6ea000       8       4       0 r-x-- libutil-2.17.so
00007f600d6ec000    2044       0       0 ----- libutil-2.17.so
00007f600d8eb000       4       4       4 r---- libutil-2.17.so
00007f600d8ec000       4       4       4 rw--- libutil-2.17.so
00007f600d8ed000      56      16       0 r-x-- liblber-2.4.so.2.10.7
00007f600d8fb000    2044       0       0 ----- liblber-2.4.so.2.10.7
00007f600dafa000       4       4       4 r---- liblber-2.4.so.2.10.7
00007f600dafb000       4       4       4 rw--- liblber-2.4.so.2.10.7
00007f600dafc000     328      64       0 r-x-- libldap-2.4.so.2.10.7
00007f600db4e000    2048       0       0 ----- libldap-2.4.so.2.10.7
00007f600dd4e000       8       8       8 r---- libldap-2.4.so.2.10.7
00007f600dd50000       4       4       4 rw--- libldap-2.4.so.2.10.7
00007f600dd51000       8       8       0 r-x-- libdl-2.17.so
00007f600dd53000    2048       0       0 ----- libdl-2.17.so
00007f600df53000       4       4       4 r---- libdl-2.17.so
00007f600df54000       4       4       4 rw--- libdl-2.17.so
00007f600df55000    2256     916       0 r-x-- libcrypto.so.1.0.2k
00007f600e189000    2048       0       0 ----- libcrypto.so.1.0.2k
00007f600e389000     112     112     112 r---- libcrypto.so.1.0.2k
00007f600e3a5000      52      52      52 rw--- libcrypto.so.1.0.2k
00007f600e3b2000      16       8       8 rw---   [ anon ]
00007f600e3b6000     188      40       0 r-x-- libsystemd.so.0.6.0
00007f600e3e5000    2048       0       0 ----- libsystemd.so.0.6.0
00007f600e5e5000       4       4       4 r---- libsystemd.so.0.6.0
00007f600e5e6000       4       4       4 rw--- libsystemd.so.0.6.0
00007f600e5e7000     144      36       0 r-x-- libselinux.so.1
00007f600e60b000    2044       0       0 ----- libselinux.so.1
00007f600e80a000       4       4       4 r---- libselinux.so.1
00007f600e80b000       4       4       4 rw--- libselinux.so.1
00007f600e80c000       8       4       4 rw---   [ anon ]
00007f600e80e000      52      12       0 r-x-- libpam.so.0.83.1
00007f600e81b000    2048       0       0 ----- libpam.so.0.83.1
00007f600ea1b000       4       4       4 r---- libpam.so.0.83.1
00007f600ea1c000       4       4       4 rw--- libpam.so.0.83.1
00007f600ea1d000     120      16       0 r-x-- libaudit.so.1.0.0
00007f600ea3b000    2044       0       0 ----- libaudit.so.1.0.0
00007f600ec3a000       4       4       4 r---- libaudit.so.1.0.0
00007f600ec3b000       4       4       4 rw--- libaudit.so.1.0.0
00007f600ec3c000      40       0       0 rw---   [ anon ]
00007f600ec46000      36      16       0 r-x-- libwrap.so.0.7.6
00007f600ec4f000    2044       0       0 ----- libwrap.so.0.7.6
00007f600ee4e000       4       4       4 r---- libwrap.so.0.7.6
00007f600ee4f000       4       4       4 rw--- libwrap.so.0.7.6
00007f600ee50000       4       0       0 rw---   [ anon ]
00007f600ee51000       8       8       0 r-x-- libfipscheck.so.1.2.1
00007f600ee53000    2044       0       0 ----- libfipscheck.so.1.2.1
00007f600f052000       4       4       4 r---- libfipscheck.so.1.2.1
00007f600f053000       4       4       4 rw--- libfipscheck.so.1.2.1
00007f600f054000     136     120       0 r-x-- ld-2.17.so
00007f600f249000      92      92      92 rw---   [ anon ]
00007f600f274000       4       4       4 rw---   [ anon ]
00007f600f275000       4       4       4 r---- ld-2.17.so
00007f600f276000       4       4       4 rw--- ld-2.17.so
00007f600f277000       4       4       4 rw---   [ anon ]
00007ffe90ff6000     132      20      20 rw---   [ stack ]
00007ffe91019000       8       4       0 r-x--   [ anon ]
ffffffffff600000       4       0       0 r-x--   [ anon ]
---------------- ------- ------- ------- 
total kB          112760    4340    1024

可以看到该进程内存被哪些库、哪些文件所占用,据此我们定位程序对内存的使用。

几个字段介绍一下:

  • Address:占用内存的文件的内存起始地址。
  • Kbytes:占用内存的字节数。
  • RSS:实际占用内存大小。
  • Dirty:脏页大小。
  • Mapping:占用内存的文件,[anon] 为已分配的内存,[stack] 为程序堆栈

最后的 total 为统计的总值。我们可以使用 pmap -x pid | tail -1 这样只显示最后一行,循环显示最后一行,达到监控该进程的目的。

[root@master ~]# while true; do pmap -x 7501 | tail -1; sleep 1; done
total kB          112760    4340    1024
total kB          112760    4340    1024
total kB          112760    4340    1024
total kB          112760    4340    1024

通过以上手段,我们基本上就能定位内存问题所在了,究竟是内存太小,还是进程占用内存太多,有哪些进程占用较多,这些进程又究竟有哪些地方占用较多,这些问题通过以上方法都能解决。

最后简单总结下,以上不少工具可能有人会犯选择困难症了。对于一般情况来说,查看系统内存用 free -h,分析进程内存占用用 ps 或者 top(首选 ps),深入分析选择 pmap,熟练运用这些就已经差不多了

后记

以上工具都是 Linux 自带的,当然还有很多高阶的工具,比如 atop、memstat 等等,对于内存泄漏有一个比较常用的检测工具 Valgrind

猜你喜欢

转载自blog.csdn.net/Thorne_lu/article/details/107758442
今日推荐