关键在于两个字段,buffers和cached。

你经常会发现Linux系统用了一段时间后,内存所剩无几,free命令,一看,内存全跑到

buffers和cached里面了;这个现象是正常的。访问过的磁盘文件的元数据及内容,内核都会缓存起来。这些缓存就是磁盘缓存。

Linux磁盘缓存设计特点(设计理念):

除了系统运行必须的一小部分保留外,只要有剩余内存,只要需要,就会用给磁盘缓存。(没有一个参数可以让你限定缓存的上限。2.6内核之前有一个限定参数,后来给取消了)所以会经常看到内存所剩无几的现象,这是缓存机制导致的,对应用是透明,在有内存需要时,这些内存会释放。这个过程对应用是透明的,应用可以认为系统的可用内存包括buffers和cached。)

这种设计,在大多数服务器应用场景下都有比较好的性能表现。可以说是比较可取的。

设计本身没有问题,但free命令显示的buffers和cached并不能和磁盘缓存完全对应,这是实现细节上的不足和问题。

1. buffers和cached包含了不属于磁盘缓存的内容。

由于buffers和cached实际上就是内核为所有文件映射分配的物理页的总和(page cache)。

但内核中的“文件概念”是广泛的,不仅包含了真正位于磁盘上的文件,还包含了为特殊需要创建的虚拟文件,比如:

进程间的共享内存(通过shmget API创建的内存),内核建立一个虚拟的文件和共享内存关联起来。(通过pmap命令你可以看到进程拥有的共享内存地址空间的映射字段是/SYSVXXXX字样,不是匿名的)。

非常的不幸,这些虚拟文件映射关联的page,也被算入了free命令显示的cached字段。但这部分内存没有缓存属性,在内存不足时不能按缓存的方式来回收。(使用echo

3 >/proc/sys/vm/drop_caches,无法释放掉这部分内存)

这个问题,会带来一些麻烦。比如,按照常规理解,某产品设计内存占用过高告警的条件是,空闲内存+buffers+cached小于内存总和的20%

。一般情况下没有问题,但如果产品使用了大量的共享内存,告警将失去作用。

2. buffers和cached遗漏了部分属于磁盘缓存的内容。

还是由于buffers和cached只是内核为所有文件映射分配的物理页的总和。在文件系统方面,还有一部分缓存是不和文件映射相关联的,比如内核分配的inode对象,在文件关闭时,并不会立即释放,具备缓存的属性。这部分不在基于文件映射的页面里,而是通过slab(内核内存池)分配的。

这个问题,也会带来一些麻烦,比如某产品的一个现网问题,系统物理内存用了80%,但free

top命令显示,用户进程没有占用、cached

buffer也没有占用,于是担心是不是内核层内存泄露了,担心会有宕机风险。

经过分析,其实就是之前做了类似"find /“

这样的操作,导致内核分配了太多的inode对象,并且缓存起来了。但站在用户层来看,会比较困惑和担心。

通过echo 3

>/proc/sys/vm/drop_caches可以释放这部分内存,这从侧面也证明了这部分确实属于缓存的范畴。

在最新的SUSE11 SP1系统上,free命令已经把这部分内存包含到了cached字段。

Linux可用内存统计方法

背景由于Linux缓存机制的设计,系统对缓存的使用是非常狠的,所以经常会看到某些环境内存只剩几十兆了,而应用只用了不到一半。所以在计算可用内存的时候,一定要算上缓存的部分。通常方法,就是通过free命令首行free+cached+buffers计算,或者直接使用第二行的free字段。但这个方法有时仍然会造成比较大的误差,导致性能监控等方面的问题。比如系统中使用了大量的共享内存会造成多计算可用内存;再比如对大量的文件做了查询(find /

?!!!),会导致少计算可用内存。对于这点我在《说说free命令》中有详细的说明。这里就不再赘述了。

SUSE11 SP1基于2.6.32内核,内核暴露了更多的统计接口给用户空间,把slab分为可回收和不可回收两类指标来统计。free命令也对应做了修改。解决了free命令少计算可用内存的问题。但多计算的问题还是存在。因此,在这里对统计可用内存的方法做了个总结。供需要的同学参考。(后面有空可能会开发一个统计工具)其中SUSE10由于内核版本过低(2.6.16)暴露信息不足,下面的方法仍然不能很精确,但相比通过free命令简单统计而言,一般不会造成比较大的误差。可用内存定义包括未被使用的空闲内存,以及已经被使用但用作缓存可以自动回收的部分。SUSE 10可用内存统计方法总内存:free命令首行total字段。空闲内存:free命令首行free字段。缓存:free命令首行buffers字段+cached字段。修正值1:cached字段包含了共享内存和tmpfs内存文件系统占用的内存。需要减去这两部分。这两部分内存可通过ipcs

-m -u和df命令获取。修正值2:cached字段漏掉了内核slab中可以自动回收的内存,比如xxx_inode_cache和dentry_cache。这两部分的内存的计算方法是解析/proc/slabinfo。最终的可用内存计算方法:空闲内存+缓存-修正值1+修正值2SUSE 11可用内存统计方法总内存:free命令首行total字段。空闲内存:free命令首行free字段。缓存:free命令首行buffers字段+cached字段。修正值1:cached字段包含了共享内存和tmpfs内存文件系统占用的内存。需要减去这两部分。这两部分内存之和可通过/proc/meminfo的Shmem字段直接获取。最终的可用内存计算方法:空闲内存+缓存-修正值1附1:ipcs获取共享内存占用物理内存大小# ipcs -m

-u

------ Shared Memory Status --------

segments allocated 4

pages allocated 786433pages

resident 2 #使用这个字段,单位是页,X86下一个页是4kBpages swapped 0

Swap performance: 0 attempts 0 successes附2:df获取tmpfs占用物理内存大小#

df

Filesystem 1K-blocks Used Available Use% Mounted on

/dev/sda2 20972152 4427900 16544252 22% /devtmpfs

24711780 160 24711620 1%

/dev #Used字段表示实际占用物理内存tmpfs

24711780 0 24711780 0%

/dev/shm #Used字段表示实际占用物理内存/dev/sda5 1052184 59188 992996 6% /boot

/dev/sda9 83888824 16852500 67036324 21% /iso

/dev/sda7 10490040 1142876 9347164 11% /opt

/dev/sda10 83888824 9421200 74467624 12% /src

/dev/sda8 20972152 3475104 17497048 17% /usr

/dev/sda6 5245016 328392 4916624 7% /var///增加统计工具2011.6.29///统计工具(在SUSE10、SUSE11验证通过)

1.修正可用内存多计算的情况(SUSE10 SUSE11)如下环境,在进行了大量共享内存创建使用后,free命令统计可用内存,出现了很大的误差。#echo 3

>/proc/sys/vm/drop_caches

#清理可回收的内存# free

total used free shared buffers

cached

Mem: 49423560 13609680 35813880 0

2676411686608

#仍有11G不可以回收,因为是共享内存,不具备回收属性。-/+ buffers/cache:

189630847527252

# free计算可用内存,算入了共享内存,得到47GSwap: 2104472 0 2104472

# ipcs -m -u

------ Shared Memory Status --------

segments allocated 20

pages allocated 4980737pages

resident 2883591 #共享内存有2883591

* 4 = 11534364 kB ~=

11Gpages swapped 0

Swap performance: 0 attempts 0 successes

# afree

Total: 49423560 kB #物理内存总计Free: 35816908 kB #未被使用的内存Reclaimable: 179348 kB #被使用了但是可以自动回收的内存Available:

35996256 kB #afree统计出来的可用内存去除了11G的共享内存。2.修正可用内存少计算的情况(SUSE10)如下环境,在进行了大量文件访问操作后,系统中缓存了大概600M的inode和dentry。#

free

total used free shared buffers cached

Mem: 3987316 1080908 2906408 0 163056

163848 -/+ buffers/cache:

7540043233312

#没有统计slab中的可以回收的inode和dentry。Swap: 2104472 0 2104472

# afree

Total: 3987316 kB

Free: 2906384 kB

Reclaimable: 958888 kB

Available:3865272

kB #afree统计了slab中的可以回收的inode和dentry。# echo 3

>/proc/sys/vm/drop_caches

#释放600M的inode和dentry缓存。# free

total used free shared buffers cached

Mem: 3987316 93628 3893688 0 17780 8948

-/+ buffers/cache:

669003920416

#执行drop_caches后,增加了600M,说明cached少统计了可回收的slab缓存。这600M即使不执行drop_caches也都是可用的,系统在需要的时候会自动回收。注:afree通过解析slabinfo文件统计可回收的slab,其实suse10的内核有一个全局变量slab_reclaim_pages维护了准确的可回收数量,但没有暴露给给用户空间,因此更准确的方法其实就是写一个模块,把这个变量导出到来。

afree代码如下:

#!/bin/sh

#

#Get accurate available

memory.

#

function get_meminfo()

{

grep

-w $1 /proc/meminfo | awk

-F'' '{print

$2}'

}

function show_meminfo()

{

printf "%s\td kB\n" "$1" "$2"

}

PAGE_SIZE=4 #kB, for

x86

function get_shmem_from_ipcs()

{

local _shm=0

_shm=$(ipcs -m

-u|grep'pages

resident'|awk -F'''{print

$3}')

echo$((_shm *

PAGE_SIZE))

}

function get_tmpfs_from_df()

{

local _size=""

_size=$(df

-k|awk -F'''BEGIN{total=0} {if

($1 == "tmpfs" || $1 == "devtmpfs" || $1 ==

"shm")total+=$3}END{print total}')

echo$_size

}

#inode, dentry and buffer_head is

reclaimable

function get_slab_reclaimable_from_slabinfo()

{

local _size=""

_size=$(awk

-F'''BEGIN{total=0} {if

($1~/inode/ || $1~"dentry" || $1 == "buffer_head")total+=($3 *

$4)}END{printf "%d\n", total / 1024}'/proc/slabinfo)

[ -z "$_size" ] && _size=0

echo$_size

}

free=$(get_meminfo

MemFree)

total=$(get_meminfo

MemTotal) cached=$(get_meminfo

Cached)

buffer=$(get_meminfo

Buffers)

swapcached=$(get_meminfo

SwapCached)

shmem=$(get_meminfo

Shmem)

slab_reclaimable=$(get_meminfo

SReclaimable)

nfs_unstable=$(get_meminfo

NFS_Unstable)

#the kernel does not support, no 'Shmem'

field in /proc/meminfo, we use ipc and df.

if[ -z "$shmem" ] ; then

shmem=$(($(get_shmem_from_ipcs)+$(get_tmpfs_from_df)))

fi

#the kernel does not support, no

'SReclaimable' field in /proc/meminfo, we use

/proc/slabinfo.

if[ -z "$slab_reclaimable" ]; then

slab_reclaimable=$(get_slab_reclaimable_from_slabinfo)

fi

#the kernel does not support, no

'NFS_Unstable' field in /proc/meminfo, we use null.

:)

if[ -z "$nfs_unstable" ]; then nfs_unstable=0

fi

reclaimable=$((cached + buffer +

slab_reclaimable + swapcached + nfs_unstable -

shmem))

available=$((free +

reclaimable))

show_meminfo "Total:" "$total"

show_meminfo "Free:" "$free"

show_meminfo "Reclaimable:" "$reclaimable"

show_meminfo "Available:" "$available"

linux 物理内存统计,说说free命令  + Linux可用内存统计方法相关推荐

  1. linux启动网络服务的命令,linux重启服务命令

    linux重启服务命令 重启:service 服务名 restart 或systemctl restart 服务名 service和systemctl 1.service命令 service命令其实是 ...

  2. linux添加源ip路由命令,linux添加ip、路由相关命令

    1- Linux添加永久路由 vi /etc/sysconfig/network-scripts/route-eth1 ADDRESS0=192.168.10.0 NETMASK0=255.255.2 ...

  3. linux显示当前电源功耗命令,linux命令大全之wc命令详解(统计文件字节数)

    Linux系统中的wc(Word Count)命令的功能为统计指定文件中的字节数.字数.行数,并将统计结果显示输出. 1.命令格式: wc [选项]文件... 2.命令功能: 统计指定文件中的字节数. ...

  4. linux中grep与wc命令,Linux高效数据统计命令wc

    原标题:Linux高效数据统计命令wc 主要参数 常见参数如下: -c 统计字节数. -l 统计行数. -m 统计字符数.这个标志不能与 -c 标志一起使用. -w 统计字数.注意,这里的字指的是由空 ...

  5. linux 物理内存用完了_调整linux内核尽量用内存,而不用swap

    线上一台服务器kswapd0占用大量的cpu资源,导致负载过高,什么是kswapd0? Linux uses kswapd for virtual memory management such tha ...

  6. linux显示当前电源功耗命令,linux基础命令-查看系统状态-free -m以及top命令详解...

    博文说明[前言]: 本文将通过个人口吻介绍Linux下的free命令及top命令的相关知识,在目前时间点[2017年6月19号]下,所掌握的技术水平有限,可能会存在不少知识理解不够深入或全面,望大家指 ...

  7. linux中system清屏命令,Linux磁盘管理命令

    语法:df [选项] 说明:df命令可显示所有文件系统对i节点和磁盘块的使用情况. 该命令各个选项的含义如下: -a 显示所有文件系统的磁盘使用情况,包括0块(block)的文件系统,如/proc文件 ...

  8. Linux系统运行时参数命令--Linux基础命令和工具

    目录 1 Linux基础命令和工具 1.1 grep搜索字符 1.2 find查找文件 1.3 ls显示文件 1.4 wc命令 1.5 ulimit用户资源 1.6 scp远程拷贝 1.7 dos2u ...

  9. linux的常用的wc命令,Linux系统中wc命令使用详解

    Linux系统中wc命令是统计文件文本的字节数等并显示输出.下面由学习啦小编为大家整理了linux系统中wc命令使用详解,希望对大家有帮助! Linux系统中wc命令使用详解 Linux系统中的wc( ...

最新文章

  1. java.lang.NoSuchMethodError: org.springframework.core.io.ResourceEditor错误
  2. 解决IndexClosedException: closed
  3. 用python编写一个猜年龄的小程序-用Python来写一个男女相亲小程序|码农的情人节...
  4. Oracle 备份还原
  5. 解决Exchange2010中无法显示客户端访问服务器ClientAccessArray中成员的问题
  6. java stream 分组求和_Java stream List 求和、分组操作
  7. 如何使用Google Analytics(分析)设置和跟踪YouTube频道的效果
  8. 电商促销素材|设计简洁,适合小清新文艺气质的你!
  9. mysql增删改查_MySQL的基本使用——简单的增删改查
  10. Java21天打卡Day6-switch
  11. ftp中转服务器,bat实现的ftp中转
  12. android 微博功能实现,android 新浪微博实现分享功能
  13. SharePoint传出电子邮件配置
  14. 分类与预测模型效果评价
  15. Redis Cluster集群原理+三主三从交叉复制实战+故障切换(十)
  16. WP-南邮CTF逆向第三题 Py交易
  17. 打桩(Stubbing), Mocking 和服务虚拟化的差异
  18. 巴比特 | 元宇宙每日必读:元宇宙的未来是属于大型科技公司,还是属于分散的Web3世界?...
  19. 90后生态 | 我不敢看体检报告了!!!
  20. .net cf wince 贝兹 曲线图

热门文章

  1. Android 6.0 运行时权限处理
  2. 巧妙共享Win7/Vista/XP文件夹权限
  3. 删除指定文件夹下的小于 4K的所用文件...
  4. 了解一下爬虫技术方方面面
  5. “未来已来,共赢未来!” -- 我眼中的Citrix Summit 2017 - Part 2
  6. web开发(二十一)之自定义拦截器的使用
  7. 可爱的MicrosoftAjax.js精简版(47K)
  8. 一道简单的面试题:竟然有90%的程序员不能把这个算法完全写正确。。。
  9. Linux运维之批量下载指定网站的100个图片文件,并找出大于200KB的文件
  10. webpack入门(六)——html-webpack-plugin