Linux中内存cache和buffer的区别和cache的区别

Buffer cache和page cache的区别_Linux教程_Linux公社-Linux系统门户网站
你好,游客
Buffer cache和page cache的区别
来源:Linux社区&
作者:alanwu
Page cache和buffer cache到底有什么区别呢?很多时候我们不知道系统在做IO操作的时候到底是走了page cache还是buffer cache?其实,buffer cache和page& cache是Linux中两个比较简单的概念,在此对其总结说明。
Page cache是vfs文件系统层的cache,例如 对于一个ext3文件系统而言,每个文件都会有一棵radix树管理文件的缓存页,这些被管理的缓存页被称之为page cache。所以,page cache是针对文件系统而言的。例如,ext3文件系统的页缓存就是page cache。Buffer cache是针对设备的,每个设备都会有一棵radix树管理数据缓存块,这些缓存块被称之为buffer cache。通常对于ext3文件系统而言,page cache的大小为4KB,所以ext3每次操作的数据块大小都是4KB的整数倍。Buffer cache的缓存块大小通常由块设备的大小来决定,取值范围在512B~4KB之间,取块设备大小的最大公约数。具体关于buffer cache的块大小问题可以参见我的另一篇博文《Linux中Buffer cache性能问题一探究竟》见 &。
这里我们可以通过一个小实验来观察一下buffer cache和page cache的差别。运行top命令,我们可以看到实验机器当前内存使用情况:
可以看出内存总容量为16GB左右,page cache用了将近10GB(3796K),buffer cache用了300MB(303796K),其余6GB(6255076K)空闲剩余。在这种情况下,如果对设备dm0进行裸盘写操作,即运行如下命令:
dd if=/dev/zero of=/dev/dm0 count=4096
那么,我么可以通过top命令发现,buffer cache的容量越来越大,空闲内存越来越少,相当一部分内存被buffer cache占用,并且在IO操作的过程中发现bdi(flush-254:176)线程在繁忙的进行数据回刷操作。
经过一段时间以后,大约6GB(6401432KB)的内存被buffer cache占用,89MB(89312KB)内存空闲,其余大约10GB(KB - 6401432KB)的内存还是被page cache占用。通过这个实验,可以说明对于裸盘的读写操作会占用buffer cache,并且当读写操作完成之后,这些buffer cache会归还给系统。为了验证page cache的占用情况,我做了文件系统级的读写操作,运行如下命令进行文件系统写操作:
cp /dev/zero ./test_file
这是一次文件拷贝操作,因此会采用page cache对文件数据进行缓存。通过top工具我们可以看出在数据拷贝的过程中,page cache的容量越来越大,空闲内存数量急剧下降,而buffer cache保持不变。
拷贝一定时间之后,空闲内存将为1.9GB(1959468KB),文件系统page cache增长为将近14.5GB(KB & 235108KB),buffer cache维持在235MB左右(235108KB)。
由此我们可以得出,page cache和buffer cache最大的差别在于:page cache是对文件数据的缓存;buffer cache是对设备数据的缓存。两者在实现上差别不是很大,都是采用radix树进行管理。
相关资讯 & & &
& (08月09日)
& (03月17日)
& (05/24/:37)
& (04月09日)
& (07/24/:47)
& (03/27/:20)
   同意评论声明
   发表
尊重网上道德,遵守中华人民共和国的各项有关法律法规
承担一切因您的行为而直接或间接导致的民事或刑事法律责任
本站管理人员有权保留或删除其管辖留言中的任意内容
本站有权在网站内转载或引用您的评论
参与本评论即表明您已经阅读并接受上述条款zhuw1989 的BLOG
用户名:zhuw1989
文章数:12
访问量:2724
注册日期:
阅读量:5863
阅读量:12276
阅读量:324906
阅读量:1034417
51CTO推荐博文
&关于linux下内存使用的一些疑惑
top4%8G3~4G
1Gphp1G100Mcache6Gcache&
&Linux-CacheBuffer
&linuxLinuxwindowslinuxLinuxwindowsLinuxwindows8GB
Linuxcachebuffers
cachelinuxI/0
2.6pdflush
pdflushdirty_background_ratio sysctldirty_background_ratiowakeup_bdflush()pdflushpdflushbackground_writeout()background_writeout()background_writeout():
&& dirty_background_ratio
pdflushpdflush
pdflushpdflushwb_kupdate()
Cachebuffer
& CacheCPUCPUCPUcacheCPUCPUcacheCPU
Freebuffercache: ()
Bufferbuffer cache
Cachepage cachecache
cachecachecacheIO 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.
Cachebuffer
了这篇文章
类别:┆阅读(0)┆评论(0)Linux Cache 机制探究
本文内容遵从, 可以随意转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明网址: /tech/system/linux_cache_discovery.html
经过研究了下Linux相关代码,把对Linux Cache实现的方式做一些总结。
相关源码主要在:
./fs/fscache/cache.c
Cache实现的代码
./mm/slab.c
SLAB管理器代码
./mm/swap.c
缓存替换算法代码
./mm/mmap.c
内存管理器代码
./mm/mempool.c
内存池实现代码
目录 (Contents)
0. 预备:Linux内存管理基础
创建进程fork()、程序载入execve()、映射文件mmap()、动态内存分配malloc()/brk()等进程相关操作都需要分配内存给进程。不过这时进程申请和获得的还不是实际内存,而是虚拟内存,准确的说是“内存区域”。Linux除了内核以外,App都不能直接使用内存,因为Linux采用Memory Map的管理方式,App拿到的全部是内核映射自物理内存的一块虚拟内存。malloc分配很少会失败,因为malloc只是通知内存App需要内存,在没有正式使用之前,这段内存其实只在真正开始使用的时候才分配,所以malloc成功了并不代表使用的时候就真的可以拿到这么多内存。据说Google的tcmalloc改进了这一点。
进程对内存区域的分配最终多会归结到do_mmap()函数上来(brk调用被单独以系统调用实现,不用do_mmap())。内核使用do_mmap()函数创建一个新的线性地址区间,如果创建的地址区间和一个已经存在的地址区间相邻,并且它们具有相同的访问权限的话,那么两个区间将合并为一个。如果不能合并,那么就确实需要创建一个新的VMA了。但无论哪种情况, do_mmap()函数都会将一个地址区间加入到进程的地址空间中,无论是扩展已存在的内存区域还是创建一个新的区域。同样释放一个内存区域使用函数do_ummap(),它会销毁对应的内存区域。
另一个重要的部分是SLAB分配器。在Linux中以页为最小单位分配内存对于内核管理系统物理内存来说是比较方便的,但内核自身最常使用的内存却往往是很小(远远小于一页)的内存块,因为大都是一些描述符。一个整页中可以聚集多个这种这些小块内存,如果一样按页分配,那么会被频繁的创建/销毁,开始是非常大的。
为了满足内核对这种小内存块的需要,Linux系统采用了SLAB分配器。Slab分配器的实现相当复杂,但原理不难,其核心思想就是Memory Pool。内存片段(小块内存)被看作对象,当被使用完后,并不直接释放而是被缓存到Memory Pool里,留做下次使用,这就避免了频繁创建与销毁对象所带来的额外负载。
Slab技术不但避免了内存内部分片带来的不便,而且可以很好利用硬件缓存提高访问速度。但Slab仍然是建立在页面基础之上,Slab将页面分成众多小内存块以供分配,Slab中的对象分配和销毁使用kmem_cache_alloc与kmem_cache_free。
关于SALB分配器有一份资料:
关于内存管理的两份资料:
1. Linux Cache的体系
在 Linux 中,当App需要读取Disk文件中的数据时,Linux先分配一些内存,将数据从Disk读入到这些内存中,然后再将数据传给App。当需要往文件中写数据时,Linux先分配内存接收用户数据,然后再将数据从内存写到Disk上。Linux Cache
管理指的就是对这些由Linux分配,并用来存储文件数据的内存的管理。
下图描述了 Linux 中文件 Cache 管理与内存管理以及文件系统的关系。从图中可以看到,在 Linux 中,具体的文件系统,如
ext2/ext3/ext4 等,负责在文件
Cache和存储设备之间交换数据,位于具体文件系统之上的虚拟文件系统VFS负责在应用程序和文件 Cache 之间通过 read/write
等接口交换数据,而内存管理系统负责文件 Cache 的分配和回收,同时虚拟内存管理系统(VMM)则允许应用程序和文件 Cache 之间通过
memory map的方式交换数据,FS Cache底层通过SLAB管理器来管理内存。
下图则非常清晰的描述了Cache所在的位置,磁盘与VFS之间的纽带。
2. Linux Cache的结构
在 Linux 中,文件 Cache 分为两层,一是 Page Cache,另一个 Buffer Cache,每一个 Page
Cache 包含若干 Buffer Cache。内存管理系统和 VFS 只与 Page Cache 交互,内存管理系统负责维护每项 Page
Cache 的分配和回收,同时在使用 memory map 方式访问时负责建立映射;VFS 负责 Page Cache
与用户空间的数据交换。而具体文件系统则一般只与 Buffer Cache 交互,它们负责在外围存储设备和 Buffer Cache
之间交换数据。读缓存以Page Cache为单位,每次读取若干个Page Cache,回写磁盘以Buffer Cache为单位,每次回写若干个Buffer Cache。
Page Cache、Buffer Cache、文件以及磁盘之间的关系如下图所示。
Page 结构和 buffer_head
数据结构的关系如下图所示。Page指向一组Buffer的头指针,Buffer的头指针指向磁盘块。在这两个图中,假定了 Page 的大小是 4K,磁盘块的大小是 1K。
在 Linux 内核中,文件的每个数据块最多只能对应一个 Page Cache
项,它通过两个数据结构来管理这些 Cache 项,一个是 Radix Tree,另一个是双向链表。Radix Tree 是一种搜索树,Linux
内核利用这个数据结构来通过文件内偏移快速定位 Cache 项,图 4 是 radix tree的一个示意图,该 radix tree
的分叉为4(22),树高为4,用来快速定位8位文件内偏移。Linux(2.6.7) 内核中的分叉为 64(26),树高为 6(64位系统)或者
11(32位系统),用来快速定位 32 位或者 64 位偏移,Radix tree 中的每一个到叶子节点的路径上的Key所拼接起来的字串都是一个地址,指向文件内相应偏移所对应的Cache项。
查看Page Cache的核心数据结构struct address_space就可以看到上述结构(略去了无关结构):
struct address_space
struct inode
/* owner: inode, block_device */
struct radix_tree_root
/* radix tree of all pages */
unsigned lo
/* number of total pages */
struct address_space
/* ditto */
} __attribute__((aligned(sizeof(long))));
下面是一个Radix Tree实例:
另一个数据结构是双向链表,Linux内核为每一片物理内存区域(zone)
维护active_list和inactive_list两个双向链表,这两个list主要用来实现物理内存的回收。这两个链表上除了文件Cache之 外,还包括其它匿名(Anonymous)内存,如进程堆栈等。
相关数据结构如下:
truct page{
struct list_
//通过使用它进入下面的数据结构free_area_struct结构中的双向链队列
struct address_space *
//用于内存交换的数据结构
//当页面进入交换文件后
struct page *next_ //自身的指针,这样就可以链接成一个链表
//用于页面交换的计数,若页面为空闲则为0,分配就赋值1,没建立或恢复一次映射就加1,断开映射就减一
//反应页面各种状态,例如活跃,不活跃脏,不活跃干净,空闲
struct list_
//表示页面寿命
wait_queue_head_
struct page ** pprev_
struct buffer_head *
void * virtual
struct zone_struct * //指向所属的管理区
typedef struct free_area_struct {
struct list_head free_
//linux 中通用的双向链队列
unsigned int *
} free_area_t;
typedef struct zone_struct{
//表示该管理区在mem-map数组中,起始的页号
unsigned long inactive_clean_
unsigned long inactive_dirty_
unsigned pages_min, pages_low, pages_
struct list_head inactive_clean_
//用于页面交换的队列,基于linux页面交换的机制。这里存贮的是不活动“干净”页面
free_area_t free_area[MAX_ORDER]; //一组“空闲区间”队列,free_area_t定义在上面,其中空闲下标表示的是页面大小,例如:数组第一个元素0号,表示所有区间大小为2的 0次方的页面链接成的双向队列,1号表示所有2的1次方页面链接链接成的双向队列,2号表示所有2的2次方页面链接成的队列,其中要求是这些页面地址连续
struct pglist_data * zone_
//用于指向它所属的存贮节点,及下面的数据结构
zone_start_
zone_start_
struct page * zone_mem_
3. Cache预读与换出
内核中文件预读算法的具体过程是这样的:
对于每个文件的第一个读请求,系统读入所请求的页面并读入紧随其后的少数几个页面(不少于一个页面,通常是三个页 面),这时的预读称为同步预读。对于第二次读请求,如果所读页面不在Cache中,即不在前次预读的group中,则表明文件访问不是顺序访问,系统继续 采用同步预读;如果所读页面在Cache中,则表明前次预读命中,操作系统把预读group扩大一倍,并让底层文件系统读入group中剩下尚不在
Cache中的文件数据块,这时的预读称为异步预读。无论第二次读请求是否命中,系统都要更新当前预读group的大小。
此外,系统中定义了一个
window,它包括前一次预读的group和本次预读的group。任何接下来的读请求都会处于两种情况之一:
第一种情况是所请求的页面处于预读
window中,这时继续进行异步预读并更新相应的window和group;
第二种情况是所请求的页面处于预读window之外,这时系统就要进行同步 预读并重置相应的window和group。
下图是Linux内核预读机制的一个示意图,其中a是某次读操作之前的情况,b是读操作所请求页面不在
window中的情况,而c是读操作所请求页面在window中的情况。
Linux内核中文件Cache替换的具体过程是这样的:刚刚分配的Cache项链入到inactive_list头部,并将其状态设置为active,当内存不够需要回收Cache时,系统首先从尾部开始反向扫描
active_list并将状态不是referenced的项链入到inactive_list的头部,然后系统反向扫描inactive_list,如果所扫描的项的处于合适的状态就回收该项,直到回收了足够数目的Cache项。其中Active_list的含义是热访问数据,及多次被访问的,inactive_list是冷访问数据,表示尚未被访问的。如果数据被访问了,Page会被打上一个Refrence标记,如果Page没有被访问过,则打上Unrefrence标记。这些处理在swap.c中可以找到。
下图也描述了这个过程。
下面的代码描述了一个Page被访问它的标记为变化:
* Mark a page as having seen activity.
* inactive,unreferenced
inactive,referenced
* inactive,referenced
active,unreferenced
* active,unreferenced
active,referenced
void mark_page_accessed(struct page *page)
if (!PageActive(page) && !PageUnevictable(page) &&
PageReferenced(page) && PageLRU(page)) {
activate_page(page);
ClearPageReferenced(page);
} else if (!PageReferenced(page)) {
SetPageReferenced(page);
参考文章:
关于内存管理,Linux有一个网页:
类似的文章
分类目录分类目录
选择分类目录
生活轨迹&&(66)
&&&随笔日记&&(23)
&&&心灵感触&&(18)
技术笔记&&(174)
&&&数据库&&(84)
&&&操作系统&&(34)
&&&程序设计&&(39)
&&&架构设计&&(7)
&&&项目管理&&(3)
&&&嵌入式&&(4)
&&&人工智能&&(3)
学习研究&&(11)
&&&自然科学&&(6)
&&&经济管理&&(4)
娱乐活动&&(4)博客访问: 221668
博文数量: 79
博客积分: 1496
博客等级: 上尉
技术积分: 1176
注册时间:
IT码农一个~
IT168企业级官微
微信号:IT168qiye
系统架构师大会
微信号:SACC2013
给主人留下些什么吧!~~
yifangt:我有基本的C知识,想提高到熟练使用库和宏的程度,我想找一位C语言老师,您愿意收徒吗?联系方式:多谢!
收徒谈不上,大家共同学习。&不过我的长项是C++,&c语言的话老实说没有在产品中使用过。学习语言只是第一关阶段,要想提升,还是需要操作系统、数据结构、算法、内存、进程管理、TCP/IP网络协议等一系列的知识来铺垫。&可以推荐你看几本书《linux环境高级编程》,&《UNIX网络编程》,《TCP/IP协议详解》,《深入理解计算机系统》,&C语言一个不错的网站&:/media/index.html.&&&&&当然这是个一个漫长的过程,一下子不可能掌握这么多,需要一个迭代的过程,自己安装一个虚拟机,然后装一个linux操作系统,如CentOS,然后自己编一个最基本的HTTP服务器,通过项目学编程是最快的,祝你成功!
我有基本的C知识,想提高到熟练使用库和宏的程度,我想找一位C语言老师,您愿意收徒吗?联系方式:多谢!
有空来我家座座,一起交流,一起分享!
请登录后留言。Linux操作系统中内存buffer和cache的区别
Linux操作系统中内存buffer和cache的区别
&&& 我们一开始,先从Free命令说起。&&& Free&&& free 命令相对于top 提供了更简洁的查看系统内存使用情况:&&& $ free&&& total used free shared buffers cachedMem: 332 40 126384-/+ buffers/cache: Swap:
265000&&& Mem:表示物理内存统计&&& -/+ buffers/cached:表示物理内存的缓存统计&&& Swap:表示硬盘上交换分区的使用情况,这里我们不去关心。&&& 系统的总物理内存:255268Kb(256M),但系统当前真正可用的内存b并不是第一行free 标记的 16936Kb,它仅代表未被分配的内存。&&& 我们使用total1、used1、free1、used2、free2 等名称来代表上面统计数据的各值,1、2 分别代表第一行和第二行的数据。&&& total1:表示物理内存总量。&&& used1:表示总计分配给缓存(包含buffers 与cache )使用的数量,但其中可能部分缓存并未实际使用。&&& free1:未被分配的内存。&&& shared1:共享内存,一般系统不会用到,这里也不讨论。&&& buffers1:系统分配但未被使用的buffers 数量。&&& cached1:系统分配但未被使用的cache 数量。buffer 与cache 的区别见后面。&&& used2:实际使用的buffers 与cache 总量,也是实际使用的内存总量。&&& free2:未被使用的buffers 与cache 和未被分配的内存之和,这就是系统当前实际可用内存。&&& 可以整理出如下等式:&&& total1 = used1 + free1total1 = used2 + free2used1 = buffers1 + cached1 + used2free2 = buffers1 + cached1 + free1&&& buffer 与cache 的区别&&& 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.&&& 更详细的解释参考:Difference Between Buffer and Cache&&& 对于共享内存(Shared memory),主要用于在UNIX 环境下不同进程之间共享数据,是进程间通信的一种方法,一般的应用程序不会申请使用共享内存,笔者也没有去验证共享内存对上面等式的影响。如果你有兴趣,请参考:What is Shared Memory?&&& cache 和 buffer的区别:&&& Cache:高速缓存,是位于CPU与主内存间的一种容量较小但速度很高的存储器。由于CPU的速度远高于主内存,CPU直接从内存中存取数据要等待一定时间周期,Cache中保存着CPU刚用过或循环使用的一部分数据,当CPU再次使用该部分数据时可从Cache中直接调用,这样就减少了CPU的等待时间,提高了系统的效率。Cache又分为一级Cache(L1 Cache)和二级Cache(L2 Cache),L1 Cache集成在CPU内部,L2 Cache早期一般是焊在主板上,现在也都集成在CPU内部,常见的容量有256KB或512KB L2 Cache。&&& Buffer:缓冲区,一个用于存储速度不同步的设备或优先级不同的设备之间传输数据的区域。通过缓冲区,可以使进程之间的相互等待变少,从而使从速度慢的设备读入数据时,速度快的设备的操作进程不发生间断。&&& Free中的buffer和cache:(它们都是占用内存):&&& buffer : 作为buffer cache的内存,是块设备的读写缓冲区&&& cache: 作为page cache的内存, 文件系统的cache&&& 如果 cache 的值很大,说明cache住的文件数很多。如果频繁访问到的文件都能被cache住,那么磁盘的读IO 必会非常小。
H3C认证Java认证Oracle认证
基础英语软考英语项目管理英语职场英语
.NETPowerBuilderWeb开发游戏开发Perl
二级模拟试题一级模拟试题一级考试经验四级考试资料
港口与航道工程建设工程法规及相关知识建设工程经济考试大纲矿业工程市政公用工程通信与广电工程
操作系统汇编语言计算机系统结构人工智能数据库系统微机与接口
软件测试软件外包系统分析与建模敏捷开发
法律法规历年试题软考英语网络管理员系统架构设计师信息系统监理师
高级通信工程师考试大纲设备环境综合能力
路由技术网络存储无线网络网络设备
CPMP考试prince2认证项目范围管理项目配置管理项目管理案例项目经理项目干系人管理
Powerpoint教程WPS教程
电子政务客户关系管理首席信息官办公自动化大数据
职称考试题目
就业指导签约违约职业测评
招生信息考研政治
网络安全安全设置工具使用手机安全
3DMax教程Flash教程CorelDraw教程Director教程
Dreamwaver教程HTML教程网站策划网站运营Frontpage教程
生物识别传感器物联网传输层物联网前沿技术物联网案例分析
互联网电信IT业界IT生活
Java核心技术J2ME教程
Linux系统管理Linux编程Linux安全AIX教程
Windows系统管理Windows教程Windows网络管理Windows故障
组织运营财务资本
视频播放文件压缩杀毒软件输入法微博
数据库开发Sybase数据库Informix数据库
&&&&&&&&&&&&&&&
希赛网 版权所有 & &&

我要回帖

更多关于 内存 buffer cache 的文章

 

随机推荐