本系列记录操作系统常见性能指标,写这个主要是记录也是回顾,笔记很长,拆分了几个部分,本篇记录 内存?的性能指标
这里需要解释一些内存相关的概念,帮助理解哪些是需要关注的指标,指标有什么影响;由于水平有限,如发现有问题欢迎指正,谢谢!
Linux 内核给每个进程都提供了一个独立的虚拟地址空间,并且这个地址空间是连续的。
页表的映射下,进程就可以通过虚拟地址来访问物理内存。
页表实际上存储在 CPU 的内存管理单元 MMU 中,处理器就可以直接通过硬件,找出要访问的内存。
内核空间:高地址
栈:包括局部变量和函数调用的上下文等。栈的大小是固定的,一般是 8 MB
文件映射:包括动态库、共享内存等,从高地址开始向下增长
堆:包括动态分配的内存,从低地址开始向上增长
数据段:包括全局变量等
只读段:包括代码和常量等
文件页是映射到文件系统中的文件或通过内存映射的文件内容。它们通常用于缓存磁盘上的数据,以提高访问效率。
文件页是当文件被读取到内存中时创建的,它们可以被系统回收而不丢失数据,因为原始数据仍然保存在磁盘上。
描述:文件页可以释放回收,脏页写会磁盘再回收
常见文件页:缓存和缓冲区,通过内存映射获取的文件映射页
脏页:被应用程序修改过,并且暂时还没写入磁盘的数据
脏页回收的方式:
cat /proc/meminfo 的?Buffers 和?Cached
读写block 的时候,Buffers会增加
读写filesystem的时候,Cached 会增加
注意:从Linux内核3.10版本开始,pdflush
的功能被合并到了kworker
内核线程中。所以目前应该是 kdmflush 负责刷新
匿名页通常与用户空间的程序相关,如程序的堆和栈。它们不直接映射到磁盘上的任何文件。
匿名页是程序动态分配的内存,如果这些内存没有被交换(swap)到磁盘,那么当程序需要更多内存时,它们必须被释放。
描述:匿名页不可直接回收,可以被swap换出到磁盘后释放
常见匿名页:应用程序动态分配的堆内存
cat /proc/meminfo
中的AnonPages
字段可以显示当前系统中的匿名页数量
回收匿名页:
系统可以通过Swap机制将这些不常访问的匿名页交换到磁盘上,从而释放内存。可以通过调整/proc/sys/vm/swappiness
的值来控制这一行为,值越大就越使用swap (0-100,默认60)
# 查看内存使用情况
cat /proc/meminfo
# 调整内存回收阈值
sysctl -w vm.min_free_kbytes=10240
# 调整Swappiness值
sysctl -w vm.swappiness=60
malloc() 是 C 标准库提供的内存分配函数,对应到系统调用上,有两种实现方式,即brk()和mmap()
对小块内存(小于 128K),C 标准库使用 brk() 来分配:
大块内存(大于 128K),则直接使用内存映射 mmap() 来分配:
这些内存,都只在首次访问时才分配,也就是通过缺页异常进入内核中,再由内核来分配内存
对内存来说,如果只分配而不释放,就会造成内存泄漏,甚至会耗尽系统内存。
所以,在应用程序用完内存后,还需要调用 free() 或 unmap() ,来释放这些不用的内存。
1)回收缓存,比如使用 LRU(Least Recently Used)算法,回收最近使用最少的内存页面
2)回收不常访问的内存,把不常用的内存通过交换分区直接写到磁盘中
3)杀死进程,内存紧张时系统还会通过 OOM(Out of Memory),直接杀掉占用大量内存的进程
管理员可以通过 /proc 文件系统,手动设置进程的 oom_adj ,从而调整进程的 oom_score
oom_adj 的范围是 [-17, 15],数值越大,表示进程越容易被 OOM 杀死;
数值越小,表示进程越不容易被 OOM 杀死,其中 -17 表示禁止 OOM
例如: $(pidof sshd) 是指去查一下sshd 的 pid
echo -16 > /proc/$(pidof sshd)/oom_adj
swappiness 来确定回收比例
swappiness=0 尽可能的回收文件页
swappiness
>0 值越大越倾向于回收匿名页,并产生swapkswapd0 内核线程用来定期回收内存
/proc/sys/vm/min_free_kbytes 设置页最小阈值,其他阈值由最小值计算得来
pages_low = pages_min*5/4
pages_high = pages_min*3/2
# 查看目前页最小阈值
sysctl -a|grep min_free_kbytes
或者
cat /proc/sys/vm/min_free_kbytes
# 修改
vi /etc/sysctl.conf
vm.min_free_kbytes = 409600
# 生效
sysctl -p /etc/sysctl.conf
NUMA ( Non-Uniform Memory Access )?是一种计算机内存架构,它允许多个处理器或处理器核心拥有自己的本地内存,同时所有处理器可以访问整个系统的内存。在这种架构下,访问本地内存的速度要快于访问远端内存。
numactl
工具,可以控制进程的内存分配,使其优先使用本地内存。将进程program
绑定到节点0的CPU和内存上,未测试过
numactl --cpunodebind=0 --membind=0 program
可能会出现主机内存充足,但是因为NUMA节点内存耗尽产生OOM异常的情况,所以需要评估内存使用量。
/proc/zoneinfo ? ZONE信息
numactl -H
/proc/sys/vm/zone_reclaim_mode
这个分两种,系统的内存使用量以及进程的内存使用量
数据主要来自 /proc/meminfo 文件,就是不同软件显示的计算方式不太一样,不同版本也有所区别
一些查看系统内存使用情况的命令:
avail Mem
(可用内存):
VIRT
(虚拟内存大小):
VIRT
?通常会比?RES
?大,因为虚拟内存包括了进程可能使用的内存空间的总和,包括未映射或未使用的内存区域。RES
(常驻内存大小):
RES
?是实际占用内存的量,这个数值可以帮助我们了解进程对物理内存的消耗SHR
(共享内存大小):
SHR
?并不一定是真正的“共享”内存,它也包括了进程独有的只读内存段。关联关系:
VIRT
?=?RES
?+?SHR
?+ 未使用的虚拟内存空间avail Mem
?通常会受到?RES
?和缓存的影响,因为当系统需要更多物理内存时,可能会牺牲缓存来提供更多的可用内存作用:
avail Mem
)VIRT
)RES
)SHR
)man free
total Total installed memory (MemTotal and SwapTotal in /proc/meminfo)
used Used memory (calculated as total - free - buffers - cache)
free Unused memory (MemFree and SwapFree in /proc/meminfo)
shared Memory used (mostly) by tmpfs (Shmem in /proc/meminfo)
buffers Memory used by kernel buffers (Buffers in /proc/meminfo)
cache Memory used by the page cache and slabs (Cached and SReclaimable in /proc/meminfo)
buff/cache Sum of buffers and cache
available 无需交换的可用于启动新应用的内存;考虑了page cache 以及并非所有可回收内存都会被回收
vmstat 5 5
procs -----------memory---------- ---swap-- -----io---- -system-- ------cpu-----
r b swpd free buff cache si so bi bo in cs us sy id wa st
man vmstat
r: The number of runnable processes (running or waiting for run time).
b: The number of processes blocked waiting for I/O to complete.
单位 KB
swpd: the amount of virtual memory used.
free: the amount of idle memory.
buff: the amount of memory used as buffers.
cache: the amount of memory used as cache.
inact: the amount of inactive memory. (-a option)
active: the amount of active memory. (-a option)
很详细,但是太多了,man sar 找到-r 参数,看看
sar -r 5 5
cat /proc/meminfo | grep -E 'MemTotal|MemFree|MemAvailable|Buffers|Cached|SwapCached|SwapTotal|SwapFree'
MemTotal: 总内存大小,即物理内存的总容量
MemFree: 当前未使用的内存量
MemAvailable: 可用内存的估计值,这是一个更现代的内存计算指标,它试图反映出在不进行交换的情况下,系统可以使用的内存数量
Buffers: 内核缓冲区缓存的大小,这些缓冲区用于缓存磁盘上的块设备I/O操作
Cached: 页缓存的大小,即被内核缓存的数据大小,页缓存用于缓存文件系统的数据,提高文件访问速度
SwapCached: 缓存在交换区的内存量,当物理内存不足时,系统会将一些内存页交换到硬盘上的交换区,这个指标可以帮助我们了解有多少内存页当前在交换区
SwapTotal 和 SwapFree: 交换区的总大小和空闲大小
一些查看进程内存使用情况的命令:
top 和 ps 的内存信息,可以参考前面的内存描述
ps axu
top
pidstat -r 5 5 # 统计5秒内的内存信息,统计5次
pidstat -r -p <PID> 1 3 # 统计1秒内,PID 进程的内存情况,统计3次
04:14:48 PM UID PID minflt/s majflt/s VSZ RSS %MEM Command
minflt/s:任务每秒发生的小错误(次要错误)总数,这些错误不需要从磁盘加载内存页
例如,当进程访问一个已经映射到内存但尚未加载到物理内存的页面时会发生页缺失(page fault),内核会从交换区(swap)或缓冲区(buffer)中获取页面。
majflt/s:任务每秒发生的主要错误总数,这些错误需要从磁盘加载内存页
性能诊断:如果 minflt/s
或 majflt/s
的值很高,可能表明进程正在面临内存压力,特别是在 majflt/s
高的情况下,可能会导致系统的磁盘I/O压力增加,进而影响整体性能。
资源监控:通过监控这些指标,系统管理员可以识别哪些进程可能导致内存不足,从而需要优化程序代码或增加系统内存。
故障排除:在诊断内存泄漏或内存使用不当的情况时,这些指标可以帮助定位问题进程。
系统调优:在调优系统时,降低 majflt/s
的值是一个目标,因为它可以减少磁盘I/O,提高系统响应速度。
Buffer 是对磁盘数据的缓存,而 Cache 是文件数据的缓存,它们既会用在读请求中,也会用在写请求中。缓存命中率高,就能减少速度慢的硬盘IO,提升系统性能。