您的位置:首页 > 运维架构 > Linux

关于linux下内存使用的一些疑惑

2013-01-14 15:43 253 查看
关于linux下内存使用的一些疑惑

昨天在top命令的输出中,惊讶地发现内存可用率不足4%,我很久没有观察内存了,也不知道这个情况是什么时候出现的。大概在一个多月前,那个时候8G的内存,有3~4G空闲,当时以为内存已经足够充足,于是在以后的日常检查中忽略了内存的使用情况。

当我发现这个现象的时候,我脑子里第一反映是内存泄露或遭到内存溢出之类的***了,而实际上我对两种情况一点也不了解,也不知道该怎么办,心里多出了几许恐慌。我反复打开网站页面,也没有打开网页慢的现象,服务器上各种性能参数中,除了磁盘的I/O偶然性的高外,一切都在可接受范围之类,一时找不到解决的方法,我就打算等服务器出现故障或报警时再根据日志来处理。

今天,我一登陆服务器,就记着查看内存使用情况,发现有1G多的空闲内存,内心的恐慌减少了一些,然后我尝试这个重启各种服务,大概是重启php之后,发现空闲内存又多出了1G,感觉暂时没什么大问题了,就忙其他的了。大概过了一个多小时后,发现空闲内存仅剩100多M了,然后我一边观察内存的使用情况,一边在网上搜索解决方法,在观察中,我发现cache竟然有6G多,于是就搜索介绍内存和cache方面的文章,发现了网易上的一篇博客:http://blog.163.com/qingfeng_0105@126/blog/static/7506273820116495855762/,下面是博客的内容。
Linux内存机制-Cache与Buffer
在linux中经常发现空闲内存很少,似乎所有的内存都被系统占用了,表面感觉内存不够用了,其实不然。这是Linux内存管理的一个优秀特性,在这方面,区别于windows的内存管理。主要特点是,无论物理内存有多大,linux都将其充分利用,将一些程序调用过的硬盘数据读入内存,利用内存读写的高速特性来提高Linux系统的数据访问性能。而windows是只在需要内存时,才为应用程序分配内存,并不能充分利用大容量的内存空间。换句话说,每增加一些物理内存,Linux都将能充分利用起来,发挥了硬件投资带来的好处,而windows只将其做为摆设,即使增加8GB甚至更大。
Linux的这一特性,主要是利用空闲的物理内存,划分出一部分空间,做为cache和buffers,以此提高数据访问性能。
1、 什么是cache?
页面高速缓存(cache)是linux内核实现的一种主要磁盘缓存。它主要用来减少对磁盘I/0操作。具体地将,是通过把磁盘中的数据缓存到物理内存中,把对磁盘的访问变为对物理内存的访问。
磁盘高速缓存的价值在于两个方面:第一,访问磁盘的速度要远远低于访问内存的速度,因此,从内存访问数据比从磁盘访问速度更快。第二,数据一旦被访问,就很有可能在短期内再次被访问到。
页面高速缓存是由内存中的物理页组成的,缓存中每一页都对应着磁盘中的多个块。每当内核开始执行一个页I/O操作时(通常是对普通文件中页大小的块进行磁盘操作),首先会检查需要的数据是否在高速缓存中,如果在,那么内核就直接使用高速缓存中的数据,从而避免访问磁盘。
举个例子,当使用文本编辑器打开一个源程序文件时,改文件的数据就被调入内存。编辑该文件的过程中,越来越多的数据会相继被调入内存页。最后,当你编译它的时候,内核可以直接使用页高速缓存中的页,而不需要重新从磁盘读取该文件了。因为用户往往反反复复读取或操作同一个文件,所以页高速缓存能减少大量的磁盘操作。
2、 cache如何更新?
由于页高速缓存的缓存作用,写操作实际上会被延迟。当页高速缓存中的数据比后台存储的数据更新时,那么该数据就被称做脏数据。在内存中累积起来的脏页最终必须被写回磁盘。在以下两种情况发生时,脏页被写回磁盘:
当空闲内存低于一个特定的阈值是,内核必须将脏页写回磁盘,以便释放内存。
当脏页在内存中驻留时间超过一个特定阈值时,内核必须将超时的脏页写回磁盘,以确保脏页不会无限期地驻留在内存中。
在2.6内核中,由一群内核线程——pdflush后台回写进程统一执行两种工作。
首先,pdflush线程在系统中的空闲内存低于一个特定的阈值时,将脏页刷新回磁盘。改后台会写进程的目的在于在可用物理内存过低时,释放脏页以重新获得内存。特定的内存阈值可以通过dirty_background_ratio sysctl系统调用设置。当空闲内存比阈值:dirty_background_ratio还低时,内核便会调用函数wakeup_bdflush()唤醒一个pdflush线程,随后pdflush线程进一步调用函数background_writeout()开始将脏页写回磁盘。函数background_writeout()需要一个长整形参数,改参数指定试图写回的页面数目。函数background_writeout()会连续地写回数据,指定满足以下两个条件:
已经有指定的最小数目的页被写出磁盘。
空闲内存数已经回升,超过了阈值dirty_background_ratio。
上述条件确保了pdflush操作可以减轻系统中内存不足的压力。回写操作不会在达到这两个条件前停止,除非pdflush写回了所有的脏页,没有剩下的脏页可再被写回了。
为了满足第二个目标,pdflush后台进程会被周期性唤醒(和空闲内存是否过低无关),将那些内存中驻留时间过长的脏页写出,确保内存中不会有长期存在的脏页。如果系统发生崩溃,由于内存处于混乱之中,所以那些在内存中还没来得及写回磁盘的脏页就会丢失,所以周期性同步页高速缓存和磁盘非常重要。在系统启动时,内核初始化一个定时器,让它周期地唤醒pdflush线程,随后使其运行函数wb_kupdate()。

Cache跟buffer的区别:
Cache:高速缓存,是位于CPU与主内存间的一种容量较小但速度很高的存储区。由于CPU的速度远高于主内存,CPU直接从内存中存取数据要等待一定时间周期,cache中保存着CPU刚用过或循环使用的一部分数据,当CPU再次使用该部分数据时可从cache中直接调用,这样就减少了CPU的等待时间,提供了系统的效率。

Buffer:缓冲区,一个用于存储速度不同步的设备或优先级不同的设备之间传输数据的区域。通过缓冲区,可以使进程之间的相互等待变少,从而使从速度慢的设备读入数据时,速度快的设备的操作进程不发生间断。

Free命令输出中的buffer和cache: (它们都是占用内存):
Buffer:作为buffer cache的内存,是块设备的读写缓冲区
Cache:作为page cache的内存,文件系统的cache

如果cache的值很大,说明cache住的文件数很多,如果频繁访问到的文件都能被cache住,那么磁盘的读IO bi会非常小。
A buffer is something that has yet to be “written” to disk. A cache is something that has been “read” from the disk and stored for later use.
Buffer用来临时存需要被写到硬盘的数据
Cache用来临时从硬盘上读取的数据,这个数据是最近经常被用到的
Cache更多的时候是用来读的,buffer是用来写的

看完这篇博客,觉得自己还有很多知识要学,同时要进一步观察内存使用情况,观察服务器性能及其变化。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  linux buffer cache