简介
当你读写文件的时候,Linux内核为了提高读写效率与速度,会将文件在内存中进行缓存,这部分内存就是Cache Memory(缓存内存)。
cache memory分为buffered cache和page cache,buffered cache针对磁盘读写的文件,page cache针对文件inode的读写。
即使你的程序运行结束后,Cache Memory也不会自动释放。这就会导致你在Linux系统中程序频繁读写文件后,你会发现可用物理内存会很少。其实这缓存内存(Cache Memory)在你需要使用内存的时候会自动释放,所以你不必担心没有内存可用。虽然在机制上进程需要内存时会自动释放cache,但不排除释放不及时或者释放的内存由于存在碎片不满足进程内存需求,linux提供这样一个参数/proc/sys/vm/min_free_kbytes,用来确定系统开始回收内存的阈值。
另外网上很多关于buffer和cache区别的说法,我把我自己觉得正确的写下来:
cache: cpu与内存之间容量较小但速度很快的存储器,因为cpu的速度远远高于内存的速度,cpu从内存中读取数据需很长的时间,而cache保存着cpu刚用过的数据或循环使用的部分数据,这时从cache中读取数据会更快,减少了cpu等待的时间,提高了系统的性能。
buffer: 内存与硬盘之间,保护硬盘和减少网络传输的次数,当然也可以提高速度,部分经常访问的数据会从buffer读取而不会从硬盘读取。
而上面所说的page cache和buffer cache都是文件系统相关的,可能应该都属于buffer? 因为cpu的cache我们是看不到的,内核能看到的是buffer,而且page cache和buffer cache本身是内核为了提高效率而出现,所以说page cache和buffer cache应该都属于buffer。
/proc/sys/vm/min_free_kbytes
代表系统保留空闲内存的最低限
min_free_kbytes=4*sqrt(lowmem_kbytes)注lowmem_kbytes即可认为是系统内存大小。
计算出来的值有最小和最大的限制,最小为128k,最大为64M
可以看出min_free_kbytes随着内存的增大不是线性增长,因为没有必要预留出过多的内存,能保证紧急时刻的使用量便足够。
watermark[min]=min_free_kbytes换算成page单位即可
watermark[low]=watermark[min]*5/4
watermark[high]=watermark[min]*3/2
可以通过cat /proc/zoneinfo来查看每个zone的watermark
watermark[high] > watermark[low] > watermark[min]
当系统的空闲内存小于watermark[low]时,开始启动内核线程kswapd进行内存回收(每个zone一个),直到该zone的空闲内存数量达到watermark[high]后停止回收。
如果上层申请内存的速度太快,导致空间内存降至watermark[min]后,内存就会进行direct reclaim(直接回收),即直接在应用程序的进程上下文中进行回收,再用回收上来的空闲内存页满足内存申请,因此实际会阻塞应用程序,带来一定的延迟响应,而且可能会触发系统OOM,这是因为watermark[min]以下的内存属于系统的自留内存,用以满足特殊使用,所以不会给用户态的普通申请来用。
min_free_kbytes大小的影响
min_free_kbytes设的越大,就会较早的启动kswapd进行回收,使得系统预留过多的内存,从而在一定程度上降低了应用程序可使用的内存量。极端情况下设置min_free_kbytes接近内存大小时,留给应用程序的内存太小而可能会频繁的导致OOM的发生。
min_free_kbytes设的过小,则导致系统预留内存过小。kswapd回收过程中也会有少量的内存分配行为(会设上PF_MEMALLOC)标志,这个标志会允许kswapd使用预留内存;另外一种情况是被OOM选中杀死的进程在退出过程中,如果需要申请内存也可以使用预留部分。这两种情况让他们使用预留内存可以避免系统进入deadlock状态。
参考:http://kernel.taobao.org/index.php?title=Kernel_Documents/mm_sysctl
/proc/sys/vm/drop_caches
如果你希望手动去释放Cache Memory(缓存内存)的话也是有办法的。
一般情况下不需要特意去释放已经使用的cache。这些cache起来的内容可以增加文件读写的效率以及速度。
1. free pagecache
echo 1 > /proc/sys/vm/drop_caches
2. free dentries and inodes
echo 2 > /proc/sys/vm/drop_caches
3. free pagecache,dentries and inodes
echo 3 > /proc/sys/vm/drop_caches
使用free查看内存
[root@ahsq proc]# free
total used free shared buffers cached
Mem: 515588 295452 220136 0 2060 64040
-/+ buffers/cache: 229352 286236
Swap: 682720 112 682608
第一行用全局角度描述系统使用的内存情况。
total——总物理内存
used——已使用内存,一般情况这个值会比较大,因为这个值包括了cache+buffer
free——完全未被使用的内存
shared——应用程序共享内存
buffers——作为buffer cache的内存,是块设备的读写缓冲区
cached——作为page cache的内存,用于文件系统的cache
total=used+free
第三行
-buffers/cache=used-buffers-cached 应用程序使用的内存大小
+buffers/cache=free+buffers+cached 可供应用程序使用的内存大小
另外使用free -lm可以查看high mem和low mem
系统内存分为high mem和low mem,64位的系统将所有的内存划到lowmem中,lowmem为寻址内存,防止lowmem不够用,而32位系统是分开的,上限为896M
如果/proc/sys/vm/min_free_kbytes设定值大于系统lowmem,系统会认为没有足够的内存而触发OOM killer杀掉占用内存最高的进程,所以导致sshd等进程被杀死,从而造成无法登录。(因为min_free_kbytes是系统预留的内存,而lowmem-min_free_kbytes是应用程序可以使用的内存,应用程序没有可用的内存会触发OOM)
/proc/meminfo
MemTotal: 所有可用RAM大小 (即物理内存减去一些预留位和内核的二进制代码大小)
MemFree: LowFree与HighFree的总和
Buffers: 用来给块设备做的缓冲大小(只记录文件系统的metadata以及 tracking in-flight pages,就是说 buffers是用来存储,目录里面有什么内容,权限等等。)
Cached: 用来给文件做缓冲大小(直接用来记忆我们打开的文件). 它不包括SwapCached
SwapCached: 已经被交换出来的内存,但仍然被存放在swapfile中。用来在需要的时候很快的被替换而不需要再次打开I/O端口。
Active: 最近经常被使用的内存,除非非常必要否则不会被移作他用.
Inactive: 最近不经常被使用的内存,非常用可能被用于其他途径.
HighTotal:
HighFree: 高位内存是指所有在860MB以上的内存空间,该区域主要用于用户空间的程序或者是缓存页面。内核必须使用不同的手法使用该段内存,因此它比低位内存要慢一些。
LowTotal:
LowFree: 低位可以达到高位内存一样的作用,而且它还能够被内核用来记录一些自己的数据结构。
SwapTotal: 交换空间的总和
SwapFree: 从RAM中被替换出暂时存在磁盘上的空间大小
Dirty: 等待被写回到磁盘的内存大小。
Writeback: 正在被写回到磁盘的内存大小。
Mapped: 影射文件的大小。
Slab: 内核数据结构缓存
VmallocTotal: vmalloc内存大小
VmallocUsed: 已经被使用的虚拟内存大小。
VmallocChunk: largest contigious block of vmalloc area which is free
CommitLimit:
Committed_AS: