Linux系统排查1——内存篇

  常见工作中,计算机系统的资源主要包括CPU,内存,硬盘以及网络,过度使用这些资源将使系统陷入困境。本系列一共四篇博文,结合我在实习期间的学习,介绍一些常见的Linux系统排障工具及方法。

  第1篇——内存篇

  第2篇——CPU篇

  第3篇——磁盘I/O篇

  第4篇——网络篇

  事实上,当上述服务器系统资源中的任何一个遭遇瓶颈,都会带来服务器性能的下降,典型的症状就是系统运行迟缓。

  本文从以下几个角度介绍Linux系统内存相关的排查。

  1. 内存的使用率如何查看,使用率真的很高吗

  2. 内存用在哪里了

  3. 内存优化可以有哪些手段

1. 内存硬件查看

# dmidecode -t memory

# dmideocde -t memory
//以下为命令输出节选
# dmidecode 2.12
# SMBIOS entry point at 0x7f6be000
SMBIOS 2.5 present.

Handle 0x0005, DMI type 16, 15 bytes
Physical Memory Array
    Location: System Board Or Motherboard
    Use: System Memory
    Error Correction Type: Single-bit ECC
    Maximum Capacity: 192 GB
    Error Information Handle: Not Provided
    Number Of Devices: 18

Handle 0x0010, DMI type 6, 12 bytes
Memory Module Information
    Socket Designation: DIMM06
    Bank Connections: 0 0
    Current Speed: 1 ns
    Type: DIMM
    Installed Size: 8192 MB (Single-bank Connection)
    Enabled Size: 8192 MB (Single-bank Connection)
    Error Status: OK

Handle 0x0011, DMI type 17, 27 bytes
Memory Device
    Array Handle: 0x0005
    Error Information Handle: Not Provided
    Total Width: 72 bits
    Data Width: 64 bits
    Size: 8192 MB
    Form Factor: DIMM
    Set: None
    Locator: DIMM06
    Bank Locator: BANK06
    Type: Other
    Type Detail: Unknown
    Speed: 800 MHz
    Manufacturer: Hynix
    Serial Number: 5781322C
    Asset Tag: Unknown
    Part Number: HMT31GR7BFR4C-H9

  通过dmidecode工具可以查看很多硬件相关的数据,这里仅以内存为例。我们可以看到,服务器最大支持内存扩充为192GB,目前已经安装了一块海力士(Hynix)生产的8GB内存,该内存插在主板的第六个DIMM插槽上面(物理插槽又称socket)。

  该命令能够给出物理内存的许多详细信息,本文并不一一介绍。

2. 内存的大体使用情况

free -m/-h

  free命令用来查看系统内存的整体使用情况。

# free -m
             total       used       free     shared    buffers     cached
Mem:         11972       6345       5627          1        305       2140
-/+ buffers/cache:       3899       8073
Swap:          856          0        856

  free -m以MB为单位显示整个系统的内存使用情况,free -h则自动选择以适合理解的容量单位显示:

# free -h
             total       used       free     shared    buffers     cached
Mem:           11G       6.2G       5.5G       1.2M       305M       2.1G
-/+ buffers/cache:       3.8G       7.9G
Swap:         856M         0B       856M

  可以看到系统内存12GB(总可用11.7GB),当前已用6.2G,剩余5.5GB。这个例子中我们看到系统的内存使用并不高,但即便free命令显示的"used"的值很高,接近total的值,那么系统就真的没有内存空间了吗?

  我们可以看到free 命令下面有一行“-/+ buffers/cache”,该行显示的used是上一行“used”的值减去buffers和cached的值,同时该行的free是上一行的free加上buffers和cached的值。这里可以看到,尽管第一行的used显示共使用了6.2GB的物理内存,但除去buffers和cached数据后,实际仅仅占用了3.8GB的内存,而如果剩余空间加上buffers和cached数据当前占用的内存,将达到8BG之多。

  这是因为buffers和cache数据是动态变化的,内存充足时,内核出于性能考虑会进行一定的缓存,当内存空间不足时,buffers, cached占用的空间是可以为了程序释放的。

  因此判断系统内存是否耗竭的实际指标是看减去buffer和cache的空间后used空间是否依旧很大,以及交换空间是否被大量占用。显然这个例子不符合内存耗竭的情形。

  那么buffers与cached又有什么区别呢?

  (1) buffers:记录文件系统的metadata,例如目录里面有什么内容,权限等等;

  (2) cached:用来给文件做缓冲,缓存刚刚访问的文件。

3. 哪些进程消耗内存比较多?

top

  top命令用来查看具体进程消耗的内存空间。

# toptop - 14:45:43 up 35 days,  2:54,  2 users,  load average: 0.35, 0.23, 0.21
Tasks: 213 total,   3 running, 210 sleeping,   0 stopped,   0 zombie
%Cpu(s):  2.1 us,  2.2 sy,  0.0 ni, 95.3 id,  0.3 wa,  0.0 hi,  0.1 si,  0.0 st
KiB Mem:  12260128 total,  6502480 used,  5757648 free,   312864 buffers
KiB Swap:   877564 total,        0 used,   877564 free.  2192620 cached Mem

  top 命令查看系统的实时负载, 包括进程、CPU负载、内存使用等等;

  进入top的实时界面后,默认按照CPU的使用率排序,通过“shift+m”按键将进程按照内存使用情况排序,可以查看哪些进程是当前系统中的内存开销“大户”。

  top命令中,按下 f 键,进入选择排序列的界面,这里可以选择要显示的信息列,要按照哪些信息列进行排序等,该界面上有简要的介绍,这里不再赘述。

  可以看到top命令也会显示系统整体的内存使用情况,同样包括了total, used, free, buffers, cached等,需要注意的是,这里并没有像free命令那样提供-/+ buffers/cached之后的值,因此需要经过额外计算才能获得当前系统实际剩余的可用内存。

  另一方面,我们查看不同进程的内存开销,

  PID USER      PR  NI    VIRT    RES    SHR S  %CPU %MEM     TIME+ COMMAND
 1501 mysql     20   0  655848 309724   9928 S   0.7  2.5 266:53.23 mysqld
 2816 rabbitmq  20   0 2444216 248528   2612 S   1.7  2.0 868:40.86 beam.smp
22589 nova      20   0  402236 144884   4084 S   0.0  1.2  17:42.08 nova-api
22591 nova      20   0  401848 144508   4092 S   0.0  1.2  17:44.65 nova-api
22590 nova      20   0  401312 143884   4068 S   0.0  1.2  17:47.23 nova-api
22588 nova      20   0  400592 143260   4080 S   0.0  1.2  17:45.53 nova-api 

  通过%MEM列,可以查看哪几个进程占用了大量的内存,在缓解内存不足的紧急情况时,可以终止这些占用内存较多的进程。

  top命令中有以下与内存相关的数据列:

  (1)VIRT:虚拟内存,是进程申请的虚拟内存总量;

  (2)RES: 常驻内存,是进程切实使用的物理内存量,free命令中看到的used列下面的值,就包括常驻内存的加总,但不是虚拟内存的加总;

  (3)SHR:共享内存,比如共享库占用的内存等。

 4. 交换空间

# swapon
# swapoff
# mkswap

  使用free命令可以查看内存的总体使用,显示的内容也包括交换分区的大小,可以使用swapon,swapoff,命令开启或关闭交换空间,交换空间是磁盘上的文件,并不是真正的内存空间。

例如:关闭交换分区

# swapoff -a
# free
             total       used       free     shared    buffers     cached
Mem:      12260128    6497332    5762796       1256     312980    2191960
-/+ buffers/cache:    3992392    8267736
Swap:            0          0          0

  此时交换分区显示全为0,说明系统没有开启交换分区。swapon命令可以启用交换分区。

  当内存不足时,系统会选择通过:1.将部分不常被访问的内存页交换到内存空间,或2.删除部分cache的文件来释放内存空间。

  系统的可用内存一般等于物理内存 + 交换分区。交换分区在磁盘上, 因此速度比内存读写要慢得多。

  交换分区实际上就是磁盘上的文件,可以通过mkswap命令来创建交换空间。

5. 内核态内存占用

# slabtop

  slab系统用来处理系统中比较小的元数据,如文件描述符等,进而组织内核态的内存分配。

  一个slab包含多个object,例如dentry这些数据结构就是object,可以通过slabtop命令查看系统中活动的object的数量与内存占用情况,从而了解哪些数据结构最占用内核态的内存空间。

例如:使用slabtop命令查看内核数据结构及内存占用

 Active / Total Objects (% used)    : 1222616 / 1575898 (77.6%)
 Active / Total Slabs (% used)      : 39945 / 39945 (100.0%)
 Active / Total Caches (% used)     : 67 / 125 (53.6%)
 Active / Total Size (% used)       : 276332.00K / 318115.77K (86.9%)
 Minimum / Average / Maximum Object : 0.01K / 0.20K / 15.75K

  OBJS ACTIVE  USE OBJ SIZE  SLABS OBJ/SLAB CACHE SIZE NAME
848211 516003  60%    0.10K  21749       39     86996K buffer_head
266406 266158  99%    0.19K   6343       42     50744K dentry
 75300  73560  97%    0.63K   3012       25     48192K proc_inode_cache
 70224  70224 100%    0.96K   2128       33     68096K ext4_inode_cache
 56960  56489  99%    0.06K    890       64      3560K kmalloc-64
 52530  50791  96%    0.04K    515      102      2060K ext4_extent_status
 30702  29066  94%    0.19K    731       42      5848K kmalloc-192
 27076  22278  82%    0.55K    967       28     15472K radix_tree_node
 26532  26532 100%    0.11K    737       36      2948K sysfs_dir_cache
 20910  20910 100%    0.05K    246       85       984K shared_policy_node
 12712  12712 100%    0.57K    454       28      7264K inode_cache
 11536  10815  93%    0.07K    206       56       824K anon_vma
  9088   7840  86%    0.03K     71      128       284K kmalloc-32
  6752   3567  52%    0.25K    211       32      1688K kmalloc-256
  6656   6656 100%    0.02K     26      256       104K kmalloc-16
  6560   4747  72%    0.12K    205       32       820K kmalloc-128
  6656   6656 100%    0.02K     26      256       104K kmalloc-16

  通常关注1. 哪些数据结构的内存占用最大,2. 哪些类型的数据结构对应的object最多,比如inode多代表文件系统被大量引用等。

  该交互命令支持的选项与排序标准有:

选项:
--delay=n, -d n    每隔n秒刷新信息
--once, -o         只显示一次
--sort=S, -s S     按照S排序,其中S为排序标准

排序标准(shift + 对应的键):
a:根据active objects数量高低排序
b:根据 objects / slab高低来排序
c:根据cache大小排序
l:根据slab数量排序
v:根据active slabs数量排序
n:按 name 排序
o:按照 objects 数量排序
p:按照 pages / slab 的值排序
s:按照 object 大小排序
u:按照 cache 使用量排序

6. 查看内存使用的动态变化

# vmstat

  vmstat命令可以查看内存使用的动态变化,

例如: 使用vmstat动态监视内存变动

# vmstat  1
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
 r  b   swpd   free   buff  cache   si   so    bi    bo   in   cs us sy id wa st
 1  0      0 5755120 312980 2192136    0    0     1    33    1    0  5  2 92  1  0
 0  0      0 5755120 312980 2192136    0    0     0     8 2000 2770  1  2 97  0  0
 1  0      0 5755120 312980 2192136    0    0     0    24 2033 2715  1  2 96  1  0
 0  0      0 5755120 312980 2192136    0    0     0     0 1999 2317  1  2 98  0  0
 3  1      0 5754996 312980 2192136    0    0     0     4 2187 3004  6  3 91  0  0

  其中# vmstat N 代表每隔N秒更新一次数据。

7. dstat

# dstat
You did not select any stats, using -cdngy by default.
----total-cpu-usage---- -dsk/total- -net/total- ---paging-- ---system--
usr sys idl wai hiq siq| read  writ| recv  send|  in   out | int   csw
  5   2  92   1   0   0|4630B  129k|   0     0 |   0     0 |2246  2808
  2   2  93   4   0   0|   0   708k|  53k 6732k|   0     0 |2091  2828
  1   2  96   1   0   0|   0  8192B|  34k 6595k|   0     0 |2198  2621
  1   2  96   0   0   1|   0    12k|  39k 6898k|   0     0 |2209  2679
  2   2  96   0   0   0|   0  4096B|  44k 7256k|   0     0 |2217  2907
  1   2  97   0   0   0|   0     0 |  38k 7109k|   0     0 |2128  2413
  2   3  94   1   0   0|   0    24k|  37k 7295k|   0     0 |2217  2594
  2   2  96   0   0   0|   0    12k|  36k 7482k|   0     0 |2106  2613
  1   1  97   0   0   0|   0  4096B|  37k 6923k|   0     0 |2255  2516

8. 查看共享内存空间

pmap

  可以使用pmap命令查看进程使用的共享内存,包括使用的库,所在堆栈空间等。

# pmap -d 1
1:   /sbin/init
Address           Kbytes Mode  Offset           Device    Mapping
00007fb45d59c000      44 r-x-- 0000000000000000 008:00002 libnss_files-2.19.so
00007fb45d5a7000    2044 ----- 000000000000b000 008:00002 libnss_files-2.19.so
00007fb45d7a6000       4 r---- 000000000000a000 008:00002 libnss_files-2.19.so
00007fb45d7a7000       4 rw--- 000000000000b000 008:00002 libnss_files-2.19.so
00007fb45d7a8000      44 r-x-- 0000000000000000 008:00002 libnss_nis-2.19.so
00007fb45d7b3000    2044 ----- 000000000000b000 008:00002 libnss_nis-2.19.so
00007fb45d9b2000       4 r---- 000000000000a000 008:00002 libnss_nis-2.19.so
00007fb45d9b3000       4 rw--- 000000000000b000 008:00002 libnss_nis-2.19.so

  

9. 查看系统内存历史记录

# sar

  可以使用sar命令查看一个月以内的内存使用情况。

如何清理内存使用

  1. 释放占用的缓存空间

# sync     //先将内存刷出,避免数据丢失
# echo 1 > /proc/sys/vm/drop_caches //释放pagecache
# echo 2 > /proc/sys/vm/drop_caches //释放dentry和inode
# echo 3 > /proc/sys/vm/drop_caches //释放pagecache、dentry和inode

  2. 终止进程

与Linux内存相关的文件系统文件

/proc/meminfo

  内存信息

/proc/$pid/status

  进程状态信息,

/proc/$pid/statm

  进程物理内存信息

/proc/slabinfo

  slab的分布状况

/proc/vmstat

  虚拟内存信息

一些额外的小技巧

1. 降低swap的使用率:

# sysctl -a | grep swappiness
vm.swappiness = 60

  可以查看当前swap的使用

2. 限制其他用户的内存使用

# vim /etc/security/limits.conf

user1 hard as 1000 (用户user1所有累加起来,内存不超过1000kiB)
user1 soft as 800 (用户user1一次运行,内存不超过800kiB)

  

3. 大量连续内存数据:

# vim /etc/sysctl.conf

vm.nr_hugepage=20

  

4. 调节page cache(大量一样的请求 调大page cache)

vm.lowmem_reserve_ratio = 256 256 32 (保留多少内存作为pagecache 当前 最大 最小)
vm.vfs_cache_pressure=100 (大于100,回收pagecache)
vm.page.cluster=3(一次性从swap写入内存的量为2的3次方页)
vm.zone_reclaim_mode=0/1(当内存危机时,是否尽量回收内存 0:尽量回收 1:尽量不回收)
min_free_kbytes:该文件表示强制Linux VM最低保留多少空闲内存(Kbytes)。

5.  脏页

vm.dirty_background_radio=10 (当脏页占内存10%,pdflush工作)
vm.dirty_radio=40 (当进程自身脏页占内存40%,进程自己处理脏页,将其写入磁盘)
vm.dirty_expire_centisecs=3000 (脏页老化时间为30秒 3000/100=30秒)
vm.dirty_writeback_centisecs=500 (每隔5秒,pdflush监控一次内存数量 500/100=5秒)

  脏页是指已经更改但尚未刷到硬盘的内存页,由pdflush往硬盘上面刷。

时间: 2024-11-07 00:35:07

Linux系统排查1——内存篇的相关文章

Linux系统排查4——网络篇

用于排查Linux系统的网络故障. 网络排查一般是有一定的思路和顺序的,其实排查的思路就是根据具体的问题逐段排除故障可能发生的地方,最终确定问题. 所以首先要问一问,网络问题是什么,是不通,还是慢? 1. 如果是网络不通,要定位具体的问题,一般是不断尝试排除不可能故障的地方,最终定位问题根源.一般需要查看 是否接入到链路 是否启用了相应的网卡 本地网络是否连接 DNS故障 能否路由到目标主机 远程端口是否开放 2. 如果是网络速度慢,一般有以下几个方式定位问题源: DNS是否是问题的源头 查看路

(转)Linux系统排查4——网络篇

原文:http://www.cnblogs.com/Security-Darren/p/4700387.html 用于排查Linux系统的网络故障. 网络排查一般是有一定的思路和顺序的,其实排查的思路就是根据具体的问题逐段排除故障可能发生的地方,最终确定问题. 所以首先要问一问,网络问题是什么,是不通,还是慢? 1. 如果是网络不通,要定位具体的问题,一般是不断尝试排除不可能故障的地方,最终定位问题根源.一般需要查看 是否接入到链路 是否启用了相应的网卡 本地网络是否连接 DNS故障 能否路由到

Linux系统排查——CPU负载篇

本随笔介绍CPU负载的排查手段. 查看系统负载的工具:uptime,w,都能查看系统负载,系统平均负载是处于运行或不可打扰状态的进程的平均数, 可运行:运行态,占用CPU,或就绪态,等待CPU调度. 不可打扰:阻塞,正在等待I/O 1.使用uptime查看系统负载 # uptime 19:26:17 up 49 days, 7:34, 1 user, load average: 0.67, 0.51, 0.41 这里我们关注的是最后三列,即系统1分钟.5分钟.15分钟内的平均负载,判断一个系统负

linux系统安全加固基础篇1

对于强大的linux来说,我们一定程度上都会认为是她秀坚强.稳定,同时也很有魅力.更多的如何使用她,而并没有对她的安全篇有很多的涉足,抛砖引玉,简单从常用的日志审计及pam用户验证块做个实例应用. 1.操作日志审计 系统的history再一定程度上可以告诉我们都干了什么,但对于这个多用户的操作系统,从单个终端的操作日志记录方式已经不能满足对 操作命令的一个审计工作. 也许会有人提示如下: chattr +a ~/.bash_history 这种修改虽然可以避免删除.bash_history或重定

Linux系统基本的内存管理知识讲解

内存是Linux内核所管理的最重要的资源之一.内存管理系统是操作系统中最为重要的部分,因为系统的物理内存总是少于系统所需要的内存数量.虚拟内存就是为了克服这个矛盾而采用的策略.系统的虚拟内存通过在各个进程之间共享内存而使系统看起来有多于实际内存的内存容量.Linux支持虚拟内存, 就是使用磁盘作为RAM的扩展,使可用内存相应地有效扩大.核心把当前不用的内存块存到硬盘,腾出内存给其他目的.当原来的内容又要使用时,再读回内存. 一.内存使用情况监测 (1)实时监控内存使用情况 在命令行使用“Free

Linux系统排查2——CPU负载篇

本随笔介绍CPU负载的排查手段. 查看系统负载的工具:uptime,w,都能查看系统负载,系统平均负载是处于运行或不可打扰状态的进程的平均数, 可运行:运行态,占用CPU,或就绪态,等待CPU调度. 不可打扰:阻塞,正在等待I/O 例1. 使用uptime查看系统负载 # uptime 19:26:17 up 49 days, 7:34, 1 user, load average: 0.67, 0.51, 0.41 这里我们关注的是最后三列,即系统1分钟.5分钟.15分钟内的平均负载,判断一个系

Linux系统排查3——I/O篇

当磁盘无法写入的时候,一般有以下可能: 文件系统只读 磁盘已满 I节点使用完 一. 遇到只读的文件系统 文件系统自动设置成只读可能是系统自我保护的一种机制,因此需要实现弄清究竟是什么原因造成了文件系统的只读.如果想要改变文件系统的只读属性,重新挂载目标分区即可. 例1. 重新挂载改变/home分区的读写属性 # mount -o remount, rw /home -o 选项后面接了两个mount 命令的专有选项,remount是指重新挂载指定文件系统,rw指定重新挂载时的读写属性,该命令不改变

Linux性能监测:内存篇

在操作系统里,虚拟内存被分成页,在 x86 系统上每个页大小是 4KB.Linux 内核读写虚拟内存是以 "页" 为单位操作的,把内存转移到硬盘交换空间(SWAP)和从交换空间读取到内存的时候都是按页来读写的.虚拟内存管理是 Linux 内核里面最复杂的部分. 这里的讲到的 "内存" 包括物理内存和虚拟内存,虚拟内存(Virtual Memory)把计算机的内存空间扩展到硬盘,物理内存(RAM)和硬盘的一部分空间(SWAP)组合在一起作为虚拟内存为计算机提供了一个连

linux内核探索之内存管理(二):linux系统中的内存组织--结点、内存域和页帧

本文主要参考<深入linux内核架构>(3.2节)及Linux3.18.3内核源码 概述:本文主要描述了内存管理相关的数据结构:结点pg_data_t.内存域struct zone以及页帧(物理页):struct page ,以及该结构相关的一些基本概念. 1. 概述 内存划分为接点,每个结点关联到系统中的一个处理器,在内核中表示为pg_data_t. 各个结点又划分为内存域,比如DMA内存域,高端内存域,普通内存域. 内核内存域的宏: enum zone_type { #ifdef CONF