Linux性能优化和监控系列(三)——分析Memory使用状况

分析Memory使用状况

内存是影响服务器性能的一个主要因素, 当进程已经驻留内存或者系能够分配给进程足够的内存给它, CPU能顺利自如的运行. 如果发生内存不足, 服务器使用I/O channel获取数据, 由于访问I/O channel速度大约比访问内存满1000倍, 这会给服务器带了性能问题.


Page大小

操作系统以内存页管理内存, 页大小会对系统系统性能有影响. 在i386系统中, 页大小默认为4KB, 对于系统经常处理大量小文件, 这是没有问题的. 但是如果系统经常处理大文件, 页大小为4KB会使服务器性能低效, 这种情况下页大小为2M更好. 当系统使用完内存后, 这是系统会使用swap memory, 由于swap memory是一种模拟memory的硬盘, 而不是真正的内存, 所以当系统使用swap memory时, 系统会非常慢. 所以当系统速度很慢时, 首先查看swap memory使用状况, swap memory的使用情况可以通过free -m查看.

[root@rdhl ~]# free -m
             total       used       free     shared    buffers     cached
Mem:          3832       2715       1116          0         43         37
-/+ buffers/cache:       2635       1197
Swap:         3967          0       3967


如果发现系统在使用swap, 接下来做的就是需要通过vmstat -s查看使用swap的具体情况, 如果使用swap很多, 那么系统速度会很慢, 因此需要考虑增加内存或者移除使用内存很多的进程.


Active和Inactive内存

在Linux内核决定哪些内存页需要交换(swap)时, 系统根据Active memoryInactive memory来判断. 所谓Active memory就是最近被使用的内存, Inactive memory是已经有一段时间没有被使用的内存. 当内核需要从RMA到swap移动内存块时, 内核会确保只有Inactive memory的内存块会被移到. 系统的Active memoryInactive memory可以通过vmstat -s查看.

[root@rdhl ~]# vmstat -s
      3924700  total memory
      2781632  used memory
        39228  active memory
        63784  inactive memory
      1143068  free memory
        44644  buffer memory
        38348  swap cache
      4063224  total swap
            0  used swap
      4063224  free swap
         9091 non-nice user cpu ticks
           76 nice user cpu ticks
      1849895 system cpu ticks
     23999960 idle cpu ticks
       110671 IO-wait cpu ticks
            0 IRQ cpu ticks
          228 softirq cpu ticks
            0 stolen cpu ticks
     84027541 pages paged in
       358313 pages paged out
            0 pages swapped in
            0 pages swapped out
     21388189 interrupts
      2499501 CPU context switches
   1395818922 boot time
         7884 forks

从上面可以看出Active memory相对Inactive memory要小.


内核内存

当分析内存使用状况时, 内核本身使用的内存也需要考虑, 这种内存叫做slab memory, 可以通过/pro/meminfo来查看.

[root@rdhl ~]# cat /proc/meminfo
MemTotal:        3924700 kB
MemFree:         1142084 kB
Buffers:           45476 kB
Cached:            38372 kB
SwapCached:            0 kB
Active:            39284 kB
Inactive:          64612 kB
Active(anon):      10336 kB
Inactive(anon):     9880 kB
Active(file):      28948 kB
Inactive(file):    54732 kB
Unevictable:           0 kB
Mlocked:               0 kB
SwapTotal:       4063224 kB
SwapFree:        4063224 kB
Dirty:                 4 kB
Writeback:             0 kB
AnonPages:         20048 kB
Mapped:             8748 kB
Shmem:               168 kB
Slab:              78396 kB
SReclaimable:      24932 kB
SUnreclaim:        53464 kB
KernelStack:         920 kB
PageTables:         3176 kB
NFS_Unstable:          0 kB
Bounce:                0 kB
WritebackTmp:          0 kB
CommitLimit:     6025572 kB
Committed_AS:     118392 kB
VmallocTotal:   34359738367 kB
VmallocUsed:      281896 kB
VmallocChunk:   34359454008 kB
HardwareCorrupted:     0 kB
AnonHugePages:      2048 kB
HugePages_Total:       0
HugePages_Free:        0
HugePages_Rsvd:        0
HugePages_Surp:        0
Hugepagesize:       2048 kB
DirectMap4k:       10240 kB
DirectMap2M:     4184064 kB

从上可以看到内核使用slab memory的大小, 如果需要查看更加详细的内核使用内存信息, 可以使用slabtop命令.

[root@rdhl ~]# slabtop
 Active / Total Objects (% used)    : 1037851 / 1042500 (99.6%)
 Active / Total Slabs (% used)      : 16568 / 16568 (100.0%)
 Active / Total Caches (% used)     : 99 / 185 (53.5%)
 Active / Total Size (% used)       : 66243.50K / 66845.72K (99.1%)
 Minimum / Average / Maximum Object : 0.02K / 0.06K / 4096.00K
  OBJS ACTIVE  USE OBJ SIZE  SLABS OBJ/SLAB CACHE SIZE NAME
550224 550216  99%    0.02K   3821      144     15284K avtab_node
353696 353524  99%    0.03K   3158      112     12632K size-32
 25360  25266  99%    0.19K   1268       20      5072K dentry
 20617  20498  99%    0.07K    389       53      1556K selinux_inode_security
 17228  16974  98%    0.06K    292       59      1168K size-64
 13528  13525  99%    0.99K   3382        4     13528K ext4_inode_cache
 12469  12455  99%    0.10K    337       37      1348K buffer_head
  9477   9453  99%    0.14K    351       27      1404K sysfs_dir_cache
  5778   5772  99%    0.58K    963        6      3852K inode_cache
  4028   3977  98%    0.07K     76       53       304K Acpi-Operand
  3960   3948  99%    0.12K    132       30       528K size-128
  2852   2808  98%    0.04K     31       92       124K Acpi-Namespace
  2489   2451  98%    0.20K    131       19       524K vm_area_struct
  2233   1931  86%    0.05K     29       77       116K anon_vma_chain
  2160   2115  97%    0.19K    108       20       432K size-192
  1656   1408  85%    0.04K     18       92        72K anon_vma
  1357    511  37%    0.06K     23       59        92K avc_node
  1302   1288  98%    0.55K    186        7       744K radix_tree_node
   940    806  85%    0.19K     47       20       188K filp
   920    772  83%    0.04K     10       92        40K dm_io
   915    854  93%    0.25K     61       15       244K size-256
   864    772  89%    0.02K      6      144        24K dm_target_io
   784    768  97%    0.50K     98        8       392K size-512
   752    734  97%    1.00K    188        4       752K size-1024
   744    743  99%    2.00K    372        2      1488K size-2048
   645    577  89%    0.25K     43       15       172K skbuff_head_cache
   640    636  99%    0.77K    128        5       512K shmem_inode_cache
   384    384 100%    0.64K     64        6       256K proc_inode_cache
   380    236  62%    0.19K     19       20        76K cred_jar
   280    273  97%    0.53K     40        7       160K idr_layer_cache
   235    235 100%    4.00K    235        1       940K size-4096
   202      6   2%    0.02K      1      202         4K jbd2_revoke_table
   184    184 100%   32.12K    184        1     11776K kmem_cache


对于内存性能分析, 系统管理员最感兴趣的是slab使用内存大小和NAME和SIZE, 如果slab使用的内存很高, 也许这个模块发生了什么错误, 也可能需要更新内核信息.


使用ps分析内存

使用ps来调整内存使用情况的优势是ps给出服务器上所有进程的内存使用大小. 通常使用ps aux来查看内存使用情况, 其中特别需要关注VSZ和RSS, VSZ(Virtual Size)是指virtual memory使用情况, 这是进程申请的总的内存大小, RSS(Resident Size)是指进程实际使用的内存大小.

[root@rdhl ~]# ps aux | more
USER       PID %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root         1  0.0  0.0  19356  1432 ?        Ss   Mar26   0:01 /sbin/init
root         2  0.0  0.0      0     0 ?        S    Mar26   0:00 [kthreadd]
root         3  0.0  0.0      0     0 ?        S    Mar26   0:00 [migration/0]
root         4  0.0  0.0      0     0 ?        S    Mar26   0:00 [ksoftirqd/0]
root         5  0.0  0.0      0     0 ?        S    Mar26   0:00 [migration/0]
root         6  0.0  0.0      0     0 ?        S    Mar26   0:00 [watchdog/0]
root         7  0.0  0.0      0     0 ?        S    Mar26   0:00 [migration/1]
root         8  0.0  0.0      0     0 ?        S    Mar26   0:00 [migration/1]
root         9  0.0  0.0      0     0 ?        S    Mar26   0:00 [ksoftirqd/1]
root        10  0.0  0.0      0     0 ?        S    Mar26   0:00 [watchdog/1]
root        11  0.0  0.0      0     0 ?        S    Mar26   0:07 [events/0]
root        12  0.0  0.0      0     0 ?        S    Mar26   0:08 [events/1]
root        13  0.0  0.0      0     0 ?        S    Mar26   0:00 [cgroup]
root        14  0.0  0.0      0     0 ?        S    Mar26   0:00 [khelper]
root        15  0.0  0.0      0     0 ?        S    Mar26   0:00 [netns]
root        16  0.0  0.0      0     0 ?        S    Mar26   0:00 [async/mgr]
root        17  0.0  0.0      0     0 ?        S    Mar26   0:00 [pm]
root        18  0.0  0.0      0     0 ?        S    Mar26   0:00 [sync_supers]
root        19  0.0  0.0      0     0 ?        S    Mar26   0:00 [bdi-default]

从上面的输出可以发现有些进程用[]括起来, 而另外一些没有, 用[]括起来的进程是内核的一部分, 其他的是正常的进程.


有两种方法可以详细了解一个进程到底在做什么, 其中一种是到/proc下找到指定进程ID, 进入该目录找到maps文件, 该文件给出了内存怎么映射到这个进程, 比如进程使用的内存地址, 子程序和库.

7f990a7bc000-7f990a7c8000 r-xp 00000000 fd:00 2359326                    /lib64/libnss_files-2.12.so
7f990a7c8000-7f990a9c8000 ---p 0000c000 fd:00 2359326                    /lib64/libnss_files-2.12.so
7f990a9c8000-7f990a9c9000 r--p 0000c000 fd:00 2359326                    /lib64/libnss_files-2.12.so
7f990a9c9000-7f990a9ca000 rw-p 0000d000 fd:00 2359326                    /lib64/libnss_files-2.12.so
7f990a9ca000-7f990a9d1000 r-xp 00000000 fd:00 2359722                    /lib64/librt-2.12.so
7f990a9d1000-7f990abd0000 ---p 00007000 fd:00 2359722                    /lib64/librt-2.12.so
7f990abd0000-7f990abd1000 r--p 00006000 fd:00 2359722                    /lib64/librt-2.12.so
7f990abd1000-7f990abd2000 rw-p 00007000 fd:00 2359722                    /lib64/librt-2.12.so
7f990abd2000-7f990ac0b000 r-xp 00000000 fd:00 2359738                    /lib64/libnspr4.so
7f990ac0b000-7f990ae0a000 ---p 00039000 fd:00 2359738                    /lib64/libnspr4.so
7f990ae0a000-7f990ae0b000 r--p 00038000 fd:00 2359738                    /lib64/libnspr4.so
7f990ae0b000-7f990ae0d000 rw-p 00039000 fd:00 2359738                    /lib64/libnspr4.so
7f990ae0d000-7f990ae0f000 rw-p 00000000 00:00 0
7f990ae0f000-7f990ae12000 r-xp 00000000 fd:00 2359740                    /lib64/libplds4.so
7f990ae12000-7f990b011000 ---p 00003000 fd:00 2359740                    /lib64/libplds4.so
7f990b011000-7f990b012000 r--p 00002000 fd:00 2359740                    /lib64/libplds4.so
7f990b012000-7f990b013000 rw-p 00003000 fd:00 2359740                    /lib64/libplds4.so


另一种方法是使用pmap -d PID, 如:

[root@rdhl proc]# pmap -d 8290
8290:   dd if=/dev/urandom of=/dev/null
Address           Kbytes Mode  Offset           Device    Mapping
0000000000400000      48 r-x-- 0000000000000000 0fd:00000 dd
000000000060b000       8 rw--- 000000000000b000 0fd:00000 dd
0000000001aa4000     132 rw--- 0000000000000000 000:00000   [ anon ]
000000305a600000     128 r-x-- 0000000000000000 0fd:00000 ld-2.12.so
000000305a81f000       4 r---- 000000000001f000 0fd:00000 ld-2.12.so
000000305a820000       4 rw--- 0000000000020000 0fd:00000 ld-2.12.so
000000305a821000       4 rw--- 0000000000000000 000:00000   [ anon ]
000000305ae00000    1576 r-x-- 0000000000000000 0fd:00000 libc-2.12.so
000000305af8a000    2048 ----- 000000000018a000 0fd:00000 libc-2.12.so
000000305b18a000      16 r---- 000000000018a000 0fd:00000 libc-2.12.so
000000305b18e000       4 rw--- 000000000018e000 0fd:00000 libc-2.12.so
000000305b18f000      20 rw--- 0000000000000000 000:00000   [ anon ]
000000305b200000      92 r-x-- 0000000000000000 0fd:00000 libpthread-2.12.so
000000305b217000    2048 ----- 0000000000017000 0fd:00000 libpthread-2.12.so
000000305b417000       4 r---- 0000000000017000 0fd:00000 libpthread-2.12.so
000000305b418000       4 rw--- 0000000000018000 0fd:00000 libpthread-2.12.so
000000305b419000      16 rw--- 0000000000000000 000:00000   [ anon ]
000000305b600000      28 r-x-- 0000000000000000 0fd:00000 librt-2.12.so
000000305b607000    2044 ----- 0000000000007000 0fd:00000 librt-2.12.so
000000305b806000       4 r---- 0000000000006000 0fd:00000 librt-2.12.so
000000305b807000       4 rw--- 0000000000007000 0fd:00000 librt-2.12.so
00007fd95653b000   96836 r---- 0000000000000000 0fd:00000 locale-archive
00007fd95c3cc000      12 rw--- 0000000000000000 000:00000   [ anon ]
00007fd95c3d9000       4 rw--- 0000000000000000 000:00000   [ anon ]
00007ffffe83e000      84 rw--- 0000000000000000 000:00000   [ stack ]
00007ffffe988000       4 r-x-- 0000000000000000 000:00000   [ anon ]
ffffffffff600000       4 r-x-- 0000000000000000 000:00000   [ anon ]
mapped: 105180K    writeable/private: 296K    shared: 0K

使用pmap的优势是pmap给出一个进程工作时详细顺序信息, 通过这个命令能看到进程调用外部库和以[anon]结束表示通过malloc进行内存分配请求.

本文出自 “大脑原来不靠谱” 博客,请务必保留此出处http://aresy.blog.51cto.com/5100031/1386097

Linux性能优化和监控系列(三)——分析Memory使用状况,古老的榕树,5-wow.com

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。