linux 内存中 page cached 等 缓存 的查看 使用和释放
1. 缓存的使用
Linux 对 cache 的使用没有规定上限,所以有时候我们的服务器上面,缓存比程序实际使用的内存还高,但是当程序申请的时候,缓存还是可以被内核自动回收的,所以对于程序而言,缓存被归纳到了可用内存中。
2. 内存中的几个概念
内存管理从三个层次管理内存,分别是node, zone ,page; 每个 zone 都有自己的 min low high,如下,但是单位是 page
[root@iZuf61cxey3d7znb5650r6Z /]# cat /proc/zoneinfo |grep "Node 0, zone" -A4 Node 0, zone DMA pages free 3977 min 16 low 20 high 24 -- Node 0, zone DMA32 pages free 428606 min 3011 low 3763 high 4516 -- Node 0, zone Normal pages free 1809555 min 13867 low 17333 high 20800
memory zone
对于多核 NUMA 系统而言,内存是分节点的,不同的 CPU 对不同的内存节点的访问速度是不一样的,所以 CPU 会优先去访问靠近自己的内存节点(即速度相对快的内存区域)。CPU 内部是依靠 MMU 来进行内存管理的,根据内存属性的不同,MMU 将一个内存节点内部又划分了不同的 zone。
对 64-bit 系统而言(即我们现在使用的系统),一个内存节点包含三个zone:Normal,DMA32,DMA, 64 位的 x86 物理机内存从高地址到低地址分为: Normal DMA32 DMA.随着地址降低。
对 32-bit 系统而言,一个内存节点则是包括:Normal,Highmem,DMA。Highmem存在的目的是为了解决线性地址空间不够用的问题,在64-bit上由于有足够的线性地址空间所以就没了该zone。
page
内核把物理页作为内存管理的基本单位。linux 查看 OS 内存页 pagesize 的大小,返回值单位为 Bytes
[root@localhost nginx-1.8.0]# getconf PAGESIZE 4096 [root@localhost nginx-1.8.0]# getconf PAGE_SIZE 4096
3. 缓存的回收机制
Watermark
每个内存 zone 都有一个数组 watermark,内核中定义了三个 watermark ( WMARK_MIN, WMARK_LOW, WMARK_HIGH,)来表示当前系统剩余的空闲内存程度。
high: 当剩余内存在high以上时,系统认为当前内存充足。
low:当剩余内存降低到low时,系统就认为内存已经不足了,会触发kswapd内核线程进行内存回收处理
min:当剩余内存在min时,则系统内存压力非常大。会触发 direct reclaim 进行内存回收处理
Kswapd
当空闲内存可用量 小于 low 的时候,会触发 kswapd 回收内存,当 kswapd 慢慢的将内存 回收到 high 水位,就开始继续睡眠
在 NUMA 系统中,每个 node 对应一个内核线程 kswapd,kswapd 在被唤醒后将扫描各个 zone 的内存使用状态,并据此进行必要的内存回收操作,因此 kswapd 的回收方式又被称为"background reclaim"
direct reclaim
min下的内存是保留给内核使用的;一般情况下min以下的内存是不会被分配给应用程序使用的,当到达min,会触发内存的 direct reclaim
在 direct reclaim 模式下,分配和回收是同步的关系,内存分配的过程会被内存回收的操作所阻塞,增加等待的时间。
4. 查看使用的缓存
查看总的使用情况,可使用 free 等命令
[root@iZuf61cxey3d7znb5650r6Z /]# free -m total used free shared buff/cache available Mem: 15885 3781 8759 4 3344 11617 Swap: 0 0 0 [root@iZuf61cxey3d7znb5650r6Z /]# cat /proc/meminfo MemTotal: 16266412 kB MemFree: 8966696 kB MemAvailable: 11893420 kB Buffers: 123252 kB Cached: 2729212 kB SwapCached: 0 kB Active: 5156864 kB Inactive: 1150324 kB Active(anon): 3455104 kB Inactive(anon): 4336 kB Active(file): 1701760 kB Inactive(file): 1145988 kB Unevictable: 0 kB Mlocked: 0 kB SwapTotal: 0 kB SwapFree: 0 kB Dirty: 48 kB Writeback: 0 kB AnonPages: 3454724 kB Mapped: 273664 kB Shmem: 4716 kB Slab: 572464 kB SReclaimable: 417228 kB SUnreclaim: 155236 kB KernelStack: 19792 kB PageTables: 18772 kB NFS_Unstable: 0 kB Bounce: 0 kB WritebackTmp: 0 kB CommitLimit: 8133204 kB Committed_AS: 8716848 kB VmallocTotal: 34359738367 kB VmallocUsed: 50784 kB VmallocChunk: 34359593356 kB HardwareCorrupted: 0 kB AnonHugePages: 1867776 kB CmaTotal: 0 kB CmaFree: 0 kB HugePages_Total: 0 HugePages_Free: 0 HugePages_Rsvd: 0 HugePages_Surp: 0 Hugepagesize: 2048 kB DirectMap4k: 397184 kB DirectMap2M: 13234176 kB DirectMap1G: 5242880 kB [root@iZuf61cxey3d7znb5650r6Z /]#
查看具体某个程序使用的缓存
目前没有找到哪个工具比较好,找了两个年代就远就没有试。但是可以按照下面的方法,以后自己写一个。
查看哪些进程使用的物理内存最多,就找到该进程打开的文件,然后用fincore查看这些文件的缓存使用率。
#!/bin/bash #you have to install pcstat if [ ! -f /data0/brokerproxy/pcstat ] then echo "You haven't installed pcstat yet" echo "run \"go get github.com/tobert/pcstat\" to install" exit fi #find the top 10 processs' cache file ps -e -o pid,rss|sort -nk2 -r|head -10 |awk '{print $1}'>/tmp/cache.pids #find all the processs' cache file #ps -e -o pid>/tmp/cache.pids if [ -f /tmp/cache.files ] then echo "the cache.files is exist, removing now " rm -f /tmp/cache.files fi while read line do lsof -p $line 2>/dev/null|awk '{print $9}' >>/tmp/cache.files done</tmp/cache.pids if [ -f /tmp/cache.pcstat ] then echo "the cache.pcstat is exist, removing now" rm -f /tmp/cache.pcstat fi for i in `cat /tmp/cache.files` do if [ -f $i ] then echo $i >>/tmp/cache.pcstat fi done /data0/brokerproxy/pcstat `cat /tmp/cache.pcstat` rm -f /tmp/cache.{pids,files,pcstat}
思想:
https://colobu.com/2017/03/07/what-is-in-linux-cached/
pcstat:
https://github.com/tobert/pcstat
fincore
# fincore --pages=false --summarize --only-cached *
https://code.google.com/archive/p/linux-ftools/source/default/source
https://github.com/david415/linux-ftools
5. 缓存的回收
手动回收
/proc/sys/vm/drop_caches
To free pagecache: sync && echo 1 > /proc/sys/vm/drop_caches To free reclaimable slab objects (includes dentries and inodes): sync && echo 2 > /proc/sys/vm/drop_caches To free slab objects and pagecache: sync && echo 3 > /proc/sys/vm/drop_caches
1. 因为这个操作仅对 clean caches 和可回收的 slab进行回收,并不会对 dirty cache 进行回收,所以是非破坏性的。 这里的 sync 并不是避免丢失数据,而是为了最大化的释放内存。
2. 但是我们一定要尽量避免在业务高峰去操作,因为他会引发 CPU 和 I/O 操作,如果业务高峰,可能导致机器hung住
设置内核参数进行自动回收
具体参看文章: linux 内核优化 内存之缓存 写磁盘 /proc/sys/vm。
共 0 条评论