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很多, 那么系统速度会很慢, 因此需要考虑增加内存或者移除使用内存很多的进程.


ActiveInactive内存

在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进行内存分配请求.

 

posted @ 2022-01-29 11:02  专注it  阅读(643)  评论(0编辑  收藏  举报