2011年7月西安邮电学院学报Ju1.
2011第16卷第4期JOURNALOFXI'ANUNIVERSITYOFPOSTSANDTELECOMMUNICATIONSVo1.
16No.
4Linux内核中内存池的实现及应用王小银,陈莉君(西安邮电学院计算机学院,陕西西安710121)摘要:基于对Linux操作系统内存管理机制、算法和模式的分析,详细解读Linux内核2.
6版本中有关内存池的定义内涵,明确内存池的创建方法和调用原理,并给出内存池在网络文件系统中的应用.
实验表明,在内存实现及用户程序中使用内存池进行内存管理,可以减少内存碎片,提高分配速度,防止内存泄露.
关键词:Linux内核;内存池;内存管理中图分类号:TP316.
1文献标识码:A文章编号:1007—3264(2011}04—0040—04存储器是一种宝贵而又紧俏的资源,如何对它加以有效的管理,不仅直接影响到存储器的利用率,而且还对系统性能有重大影响l-1].
在Linux操作系统中,内核将物理页作为内存管理的基本单位,内存管理单元通常以页为单位进行处理.
通常我们习惯直接使用new、malloc等API函数申请分配内存.
但在申请内存时,由于所申请内存块的大小不定,当频繁使用这些API函数时会造成大量的内存碎片从而降低性能[2].
因此Linux2.
6内核引入了一种更有效的内存分配方式——内存池(MemoryPoo1).
但目前用户的应用程序仍多用默认的内存管理函数new/delete或malloc/ffee分配和释放内存,这样会有一些额外的开销,也有可能导致内存泄露.
本文对Linux操作系统内核管理方法进行分析,研究Linux内核2.
6版本中内存池定义、创建、实现及其在网络文件系统中的应用,从而用户可以在应用程序中采取内存池的分配与释放方法进行内存管理,提高内存的分配速度,防止内存泄露.
1Linux系统内存管理在Linux内存管理中,简化了分段机制,使得虚地址与线性地址总是一致的,线性空间在32位平台上为4GB的固定大小.
Linux内核这4GB的空间分为两部分,其中0至3GB是用户态空间,由各进程独占;3GB到4GB是内核态空间,由所有进程共享,但只有内核态进程才能访问E引.
Linux内存管理采用了伙伴算法,伙伴算法分配内存时,每次至少分配一个页面.
这种方法适合大块内存请求,不适合小内存区请求.
当请求分配的内存大小为几十个字节时需要例外的管理机制.
从Linux2.
2开始,内存分配时采用了一种空间和时间上都具有高效性的内存分配器——slab分配器.
图1是slab分配器的主要结构.
最高层cache—chain是一个slab缓存的链接列表,这对于最佳适配算法非常有用,可以用来查找大小最适合的缓存(遍历列表).
cache—chain的每个元素都是一个kmem_cache结构的引用(称为一个cache).
它定义了一个要管理的给定大小的对象池.
与传统的内存管理模式相比,slab缓存分配器有很多优点.
首先,内核通常依赖于对小对象的分配,它们会在系统生命周期内进行无数次分配.
slab缓存分配器通过对类似大小的对象进行缓存而提供这种功能,从而避免了常见的碎片问题.
其次,slab分配器还支持通用对象的初始化,从而避免了为同一目标而对一个对象重复进行初始化.
最后,收稿日期:2011—03—28基金项目:西安邮电学院中青年科研基金资助项目(103—0439)作者简介:王小银(1976一),女,副教授,硕士,研究方向:操作系统安全、嵌入式系统,E-mail:wangxiaoyinxy@126.
com;陈莉君(1964一),女,教授,硕士,研究方向:Linux操作系统、嵌入式系统.
万方数据第4期王小银,等:Linux内核中内存池的实现及应用·41·slab分配器还可以支持硬件缓存对齐,这允许不同缓存中的对象占用相同的缓存行,从而提高缓存的利用率并获得更好的性能.
Cache_chain图1slab分配器的主要结构2Linux内存池内存池是动态分配内存的设备,只能被特定的内核成分(即池的"拥有者")使用.
拥有者通常不直接使用内存池,当普通内存分配失败时,内核才调用特定的内存池函数来提取内存池,以得到所需的额外内存.
因此内存池只是内核内存的一个储备,用在特定的时刻.
这样做的一个显著优点是尽量避免内存碎片,使得内存分配效率得到提升[5].
一个内存池通常叠加在slab分配器之上——也就是说,它被用来保存slab对象的储备.
但是一般而言,内存池能被用来分配任何一种类型的动态内存,从整个页框到使用kmalloc函数分配的小内存区.
因此,我们可以将一般内存池处理的内存单元看成"内存元素".
引入了内存池之后,Linux内核的内存管理采取两级分配机制,即初始化时将内存池按照内存的大小分成多个级别(每个级别均是8字节的整数倍数,一般是8,16,24,…,128字节),每个级别都预先分配了2O块内存[6].
如果用户申请的内存单元大于预定义的级别(128字节),则直接调用malloc从堆中分配内存.
而如果申请的内存小于128字节,则从最相近的内存大小中申请,如果该组的内存存储量小于一定的值,就会根据算法,再次从堆中申请一部分内存加入内存池,保证内存池中有一定量的内存可以使用[7].
3Linux内核中内存池的实现Linux内核中内存池的数据结构定义在OpE.
3.
1内存池的数据结构Linux内核中内存池mempool—S的定义为typedefstructmempool_s{spinlock_tlock;intmin_nr;void**elements;void*pooldata;mempool_alloc_t*alloe;mempool_free_t*free;wait_queue_head__twait;)mempool_t;结构体中相应的字段描述如下:lock:用来保护对象字段的自旋锁.
min_nr:内存池中元素的最小个数,elements数组中的成员数量.
curr_nr:当前内存池中元素的个数,即当前ele—ments数组中空闲的成员数量elements:用来存放内存成员的二维数组,其长度为ml'n—nr,宽度是上述各个内存对象的长度,因为对于不同的对象类型,会建立相应的内存池对象,所以每个内存池对象实例的宽度都是跟其内存对象有关的.
pool—data:内存池与内核缓冲区的结合使用,这个指针通常是指向这种内存对象对应的缓存区的指针.
由于Linux采用slab技术预先为每一种内存对象分配了缓存区,每当我们申请某个类型的内存对象时,实际是从这种缓存区获取内存.
alloc:用户在创建一个内存池对象时提供的内存分配函数,这个函数可以用户编写,也可以采用内存池提供的分配函数.
free:与alloc功能相反的一个函数,内存释放函数.
wait:当内存池为空时使用的等待队列.
3.
2内存池的创建内存池函数的实现在mm/mempoo1.
C文件中定义.
内存池初始化用到了mempool_create函数,它负责为一类内存对象构造一个内存池,传递的参数包括内存池分配的最小内存成员数量、用户自定义内存分配函数、用户自定义内存析构函数.
该对象的缓存区指针,指向根据用户自定义内存分配函数所提供的可选私有数据.
mempoolcreate函数的具体实现如下:mempool_t*mempool_create(intmin_nr,mempooLalloc_t*alloc—fn,mempool—free—t万方数据·42·西安邮电学院学报2011年7月*free_fn.
void*pooLdata)treturnmempool_create_node(min_nr,alloc_fn,free_fn,pooldata,一1);}函数的形参min_nr表示内存池中最少可以分配的对象数,alloc—fn是由用户定义的对象分配函数名,free—fn是由用户定义的释放对象函数名,pool—data是用户定义对象分配函数可以访问的可选私有数据.
这个函数生成并分配一个一定大小并事先已经分配的内存池.
在mempool—create函数中调用了mempool—create—node函数.
mempool—create_node函数的实现在此不再赘述.
3.
3内存池的使用如果需要使用已经创建的内存池,则需要调用mempool_alloc函数从内存池中申请内存以及调用mempool_free函数将用完的内存归还给内存池.
3.
3.
1内存池调用函数mempool_alloc内存池调用函数mempool—alloc的函数声明如下:void*mempool—allot(mempool—tpool,intgfp_mask);该函数实现时首先进行一些必要的定义和初始化,并将用户传递进来的gfP进行配置.
然后将通过形参传递进来的gfP掩码标志去掉一GFP—WAIT和一GFP_IO两个标志,这样做的作用是试图调用用户自定义分配函数从缓存区申请一个内存对象,而不是首先从内存池中分配,如果申请不到,再从内存池中分配.
接着从内存池中获取一个内存对象,若内存池不为空,则返回给申请者一个内存对象.
并且该函数实现中考虑了在GFP—ATOMIC事件发生时,不能睡眠.
3.
3.
2内存池的释放函数mempoolfree内存池调用结束,应调用mempool_free函数释放内存池,也就是将内存对象重新放置到内存池中.
mempool—free函数声明如下:voidmempool—free(void*element,mempool—t*poo1);mempool—pool函数第一个形参element是指申请的存放内存池成员的数组,第二个形参pool指向由mempool—create()函数分配的内存池.
在mempool—free函数实现时,如果当前内存池已满,则直接调用用户内存释放函数将内存还给系统;如果内存池还有剩余空间,则将内存对象放入池中并唤醒等待队列.
4内存池在网络文件系统中的应用NFS(NetworkFileSystem)是一种分布式文件系统,允许网络中安装不同操作系统的计算机间共享文件和外设.
内存池在网络文件系统中有着广泛的应用.
在linux/fs/nfs/write.
C中,首先定义一个mempool_t类型的指针变量nfs_wdata_mempool:staticmempool—t*nfs_wdata_mempool;然后就可以根据需要申请相应的数据空间,其实现如下:'structnfs—write—data*nfs—writedata—alloc(unsignedintpagecount){structnfs—write—dataP—mempool—al—loc(nfs_wdata_mempool,GFP_NOFS);if(p){memset(p,0,sizeof(p));INIrr_LISTl_HEAD(&p一>pages);p-->npages===pagecount;if(pagecountpage_array))p-->pagevec:==p一>page_array;else(P一~pagevec—kealloc(pagecount,sizeof(struetpage*),GFP_NOFS);if(!
p-->pagevec){mempool_free(p,nfs_wdata_mempoo1);P==NULL;))}free(p);)当内存池调用结束,再将内存对象重新放置到内存池中,其实现如下:voidnfs_writedata_free(structnfs—.
write_data*p){if(p8L&(p-->pagevec!
一l~p-->page—.
array[O]))kfree(p--~pagevec);万方数据第4期王小银,等:Linux内核中内存池的实现及应用·43·mempool_free(p,nfs_wdata_mempoo1);5结束语分析了Linux2.
6内核中内存池的数据结构及实现,并对其在网络文件系统中的应甩进行了研究.
研究表明,使用内存池可以减少内存碎片,提高分配速度,便于内存管理,防止内存泄露.
将内存池的分配方法应用于用户程序,可提高效率.
但是当分配的内存大小增大的时候,使用内存池分配内存的速度有可能会有所降低.
参考文献E13汤小丹,汤子瀛,哲凤屏,等.
计算机操作系统EM].
西安:西安电子科技大学出版社,2007.
E23刘若慧,毛莺池,祁翔.
Linux操作系统EM3.
北京:人民邮电出版社,2008.
[3]陈莉君,康华.
Linux操作系统原理与应用[M].
北京:清华大学出版社,2006.
[4]吴国伟,李张,任广臣.
Linux内核分析及高级编程[M].
北京:电子工业出版社,2008.
[5]李云华.
Linux内核源代码导读[M].
北京:电子工业出版社,2009.
[6I肖竟华,陈岚.
Linux内存管理实现的分析与研究口].
计算机技术与发展.
2007,17(2):187—189.
[7]陈莉君,康华,张波译.
Linux内核设计与实现[M].
北京:机械工业出版社,2006.
[8]任桥伟.
Linux内核修炼之道EM].
北京:人民邮电出版社,2010.
ImplementationandapplicationofthememorypoolinLinuxkernelWANGXiao-yin,CHENLi-jun(SchoolofComputerScienceandTechnology,Xi'anUniversityofPostsandTelecommunications,Xi'an710121,China)Abstract:AfterthatthememorymanagementpatternofLinuxisanalyzed,thedefinitionofthememorypoolinthekernel(version2.
6)ofLinUXisunscrambled,andthemethodstocreateortransferthememo—rypoolarenaileddown,besides,anexampleisgiventOshowhowthememorypoolworksinnetworkfilesystem.
Experimentsshowthat,whenthememorypooIisintroducedformemorymanagementintomemo—ryimplementationanduserprogram,thenumberofmemorypieceswillbereduced,thespeedofdistribu—tionwillbeimproved,andtheleaksolfmemorywillbeavoide&Keywords:Linuxkernel;memorypool【;memorymanagement[责任编辑:祝剑](上接第39页)E7lDr.
RaoMikkilineni,VijaySarathy.
InfrastructuresforCollaborativeEnterprises[C]//18thIEEEIntema—tionalWorkshopsonEnablingTechnologies,2009:57—62.
[8]朱珠.
基于Hadoop的海量数据处理模型和应用[D].
北京:北京邮电大学,2008.
AmethodforfrequentsetminingbasedonMapRedueeI之ONGXiang,LILingjuan(SchoolofComputerScience,NanjingUniversityofPostsandTelecommunications,Nanjing210003,China)Abstract:ToimprovetheclassicApricrialgorithmoftheassociaterulesmining,amethodforfrequentsetminingbasedonMapReduceisproposed.
ThenewmethodcanbeimplementedbasedonaplatformofHa—doop,andthus,anexperimentalresearchcanbegiventOcomparetheperformanceofthenewmethodwiththatoftheApriori.
Theresultshowsthat,thenewmethodcantakeadvantagesofcloudcomputingtogetgoodefficiencywhenminingmassdata.
Keywords:cloudcomputing;Hadoop;Apriori;MapReduce[责任编辑:孙书娜]万方数据
vollcloud LLC首次推出6折促销,本次促销福利主要感恩与回馈广大用户对于我们的信任与支持,我们将继续稳步前行,为广大用户们提供更好的产品和服务,另外,本次促销码共限制使用30个,个人不限购,用完活动结束,同时所有vps产品支持3日内无条件退款和提供免费试用。需要了解更多产品可前往官网查看!vollcloud优惠码:VoLLcloud终生6折促销码:Y5C0V7R0YW商品名称CPU内存S...
云基yunbase怎么样?云基成立于2020年,目前主要提供高防海内外独立服务器,欢迎各类追求稳定和高防优质线路的用户。业务可选:洛杉矶CN2-GIA+高防(默认500G高防)、洛杉矶CN2-GIA(默认带50Gbps防御)、香港CN2-GIA高防(双向CN2GIA专线,突发带宽支持,15G-20G DDoS防御,无视CC)。目前,美国洛杉矶CN2-GIA高防独立服务器,8核16G,最高500G ...
麻花云怎么样?麻花云公司成立于2007年,当前主打产品为安徽移动BGP线路,数据中心连入移动骨干网。提供5M,10M大带宽云主机,香港云服务器产品,数据中心为香港将军澳机房,香港宽频机房 cn2-GIA优质线路、采用HYPER-V,KVM虚拟技术架构一、麻花云官网点击直达麻花云官方网站合肥网联网络科技有限公司优惠码: 专属优惠码:F1B07B 享受85折优惠。最新活动 :双11 云上嗨购 香港云主...
御轩池为你推荐
2020双十一成绩单2020年河南全县初二期末成绩排名?sherylsandberg这个文章什么意思 给个翻译好吗 谢谢了刘祚天Mc浩然的资料以及百科谁知道?haole018.comse.haole004.com为什么手机不能放?www.javmoo.comjavimdb是什么网站为什么打不开baqizi.cc讲讲曾子杀猪的主要内容!dadi.tv电视机如何从iptv转换成tv?javlibrary.com大家有没有在线图书馆WWW。QUESTIA。COM的免费帐号www.175qq.com最炫的qq分组www.aise.com怎么观看网页一些视频?
me域名注册 申请域名 手机域名注册 传奇服务器租用 域名查询系统 域名备案信息查询 踢楼 technetcal kdata 68.168.16.150 论坛空间 骨干网络 智能骨干网 lol台服官网 linux使用教程 优酷黄金会员账号共享 免费mysql数据库 华为云盘 香港亚马逊 1元域名 更多