Linux系统诊断之内存基础深入详解
1.背景
谈及linux内存,很多时候,我们会关注free,top等基础命令。当系统遇到异常情况时,内存问题的根因追溯,现场诊断时,缺乏深层次的debug能力。本篇幅不做深层讨论,能把当前系统的问题描述清楚,是每个SRE应该具备的最基础能力。
2. free
2.1 free命令原理
free是通过查看 /proc/meminfo 来获取内存的使用情况。但是 /proc/meminfo 这个文件又是怎么来的?我们先了解下 /proc 目录:
- /proc 是一个虚拟文件系统,该目录下的所有文件都是伪文件,该类文件只存在于内存中,并不占用空间——使用 du -sh 即可验证,该模具路下的磁盘占用都是0。
- /proc 下的所有文件都是内核调用proc_create() 接口来创建的虚拟条目。
- /proc 中的文件,大多反馈系统信息的实时情况(进程、内存、cpu、设备信息等)。
结论: /proc/meminfo 是 /proc 文件系统下保存你内存相关信息的"伪文件"。
2.2 命令输出简介
每个发行版输出都有一定差异,我们以debian8 4.19.x发行版为例。
root@4f996feeb851:~# free -m total used free shared buffers cached Mem: 1991 1909 81 4 155 836 -/+ buffers/cache: 917 1073 Swap: 1023 1 1022
大部分的命令输出意思,大家可以在man文档中找到解析,这里不做赘述。
- used: 已使用的内存 used = total - free -buffers -cached
- free: 未使用的内存 memFree & swapFree in /proc/meminfo
- shared: tmpfs使用的内存 shmem in /proc/meminfo
- buffers:被内核缓冲去使用的内存
- cached: 被页缓存和slabs使用的内存
- buffers/cache: 表示buffers和cache的总和
- swap: 交换分区的使用量
2.3 buffer和cache会使用内存吗?
答案是肯定的,先来了解下buffer和cache。
- cache(缓存)官方定义是用来弥补高速设备和低速设备之间的访问速度不匹配而预留的一段空间,用来加快资源的访问。 简单讲就是读的更快。
- buffer(缓冲)是为了做资源写入整形,计算机遇到大量的“小规模IO”时,会将其整形为少量的“大规模IO”,降低写入次数。从而达到“写资源”合理利用的效果。
然而,free命令所展示的buffer和cache 有点狭义的意思——free展示的buffer表示 块设备所占用的缓存 、free展示的cache表示普通文件占用的the page cache(缓存页) 。
总之,buffer和cache使用的内存都是用来加速Linux读写性能,如果有新的进程需要内存,系统会将buffer和cache占用的内存回收,并重新分配给进程使用。
2.4 其他内存概念
RSS & VSZ & PSS & USS
- RSS(Resident Set Size):进程实际使用的物理内存大小,包括sharedMem。
- VSZ(Virtual Memory Size):进程所有能够访问到的内存大小,包括因为缺页中断,被swap出去的内存大小,以及sharedMem。
- PSS(Proportional Set Size):按照比例将内存的大小加到RSS中。
- USS(Unique Set Size):进程独占的物理内存大小。
usedMem分为 active & inactive
- active:表示这部分的内存正在被某个特定的进程使用,不太可能被收回。
- inactive:表示这部分内存是被分配到某个不在running状态的进程,有可能会被回收。
Linux会维护一个LRU List用来管理活动页和非活动页的回收。 简单讲, 越接近该List的末尾,该页面被回收的概率就越大,反之,越接近列首,则更不易被回收。 linux内核会维护两类LRUList——active list和inactive list,刚访问过的页面放入active list,长时间未访问的页面放入inactive list,内核线程kswapd会定期将active list中的页面移至"htmlcode">
1. 简介 swappiness范围0-100,默认60 0: 表示禁止使用swap 60: 默认 100: 疯狂使用swap 2. 操作方法 # sysctl vm.swappiness=VALUE # sysctl vm.swappiness=20 或者 # echo VALUE > /proc/sys/vm/swappiness # echo 30 > /proc/sys/vm/swappiness
通过在线增加swap分区大小,临时控制内存泄露,内存不够用等异常。
1. 需要root用户 2. 创建存储文件 # dd if=/dev/zero of=/home/swap2G bs=1024 count=2M 3. 安全设置 # chown root:root /home/swap2G # chmod 0600 /home/swap2G 4. 创建liunx交换分区 # mkswap /home/swap2G 5. enable 交换分区 # swapon /home/swap2G 6. 更新fstab文件【注意: 部分操作系统不需要】 # vim /etc/fstab /home/swap2G none swap sw 0 0 7. 检查是否生效 #free -m 8. 卸载swap分区 # swapoff /home/swap2G
5.2 缓存相关
sync; echo 3 > /proc/sys/vm/drop_caches 0:不释放 1:释放页缓存 2:释放 dentries 和 inodes 3:释放所有缓存
5.3 OOM相关
- vm.panic_on_oom
- 是否在触发 oom 机制时触发 kernel panic。0表示关闭(推荐),1表示打开。 kernel panic是指计算机遇到了致命的错误,并且他不知道该怎么处理时的一种动作——可以类比windows的蓝屏。 我们当然不希望每次计算机在oom时就直接蓝屏。推荐设置为0
- vm.overcommit_kbytes:
- 用于限制进程能够申请的最大内存,0表示不设置,如果设置其他数值,比如400,则进程能够申请到的最大内存为 swap+400kBytes
- vm.overcommit_ratio:
- 定义了进程可以使用的最大内存(百分比模式),默认为50。表示配置50之后,进程不允许申请超过 swap + 50% * 物理内存总量 以上的内存
- vm.oom_kill_allocating_task (Linux 2.6.24+支持)
- 这在内存不足的情况下启用或禁用杀死OOM触发任务。0表示禁用(默认),1表示启用。可以理解为oom机制的开关,默认为禁用——表示要让oom触发器正常执行。
- 其他有兴趣的话,可以自行man proc
下一篇:探索PowerShell(七) PowerShell变量