欢迎来到课桌文档! | 帮助中心 课桌文档-建筑工程资料库
课桌文档
全部分类
  • 党建之窗>
  • 感悟体会>
  • 百家争鸣>
  • 教育整顿>
  • 文笔提升>
  • 热门分类>
  • 计划总结>
  • 致辞演讲>
  • 在线阅读>
  • ImageVerifierCode 换一换
    首页 课桌文档 > 资源分类 > DOCX文档下载  

    brk和sbrk工作原理.docx

    • 资源ID:587062       资源大小:30.19KB        全文页数:8页
    • 资源格式: DOCX        下载积分:5金币
    快捷下载 游客一键下载
    会员登录下载
    三方登录下载: 微信开放平台登录 QQ登录  
    下载资源需要5金币
    邮箱/手机:
    温馨提示:
    用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)
    支付方式: 支付宝    微信支付   
    验证码:   换一换

    加入VIP免费专享
     
    账号:
    密码:
    验证码:   换一换
      忘记密码?
        
    友情提示
    2、PDF文件下载后,可能会被浏览器默认打开,此种情况可以点击浏览器菜单,保存网页到桌面,就可以正常下载了。
    3、本站不支持迅雷下载,请使用电脑自带的IE浏览器,或者360浏览器、谷歌浏览器下载即可。
    4、本站资源下载后的文档和图纸-无水印,预览文档经过压缩,下载后原文更清晰。
    5、试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。

    brk和sbrk工作原理.docx

    brk和Sbrk及内存分配函数相关brk和Sbrk主要的工作是实现虚拟内存到内存的映射.在GNUC中,内存分配是这样的:每一个进程可访问的虚拟内存空间为3G,但在程序编译时,不可能也没必要为程序分配这么大的空间,只分配并不大的数据段空间,程序中动态分配的空间就是从这一块分配的。如果这块空间不够,malloc函数族(realloc,CalIoC等)就调用Sbrk函数将数据段的下界移动,Sbrk函数在内核的管理下将虚拟地址空间映射到内存,供malloc函数使用。(参见Iinux内核情景分析)#include<unistd.h>intbrk(void*end_data_segment);void*sbrk(ptrdiffjincrement);DESCRIPTIONbrksetstheendofthedatasegmenttothevaluespecifiedbyend_data_segment,whenthatvalueisreasonable,thesystemdoeshaveenoughmemoryandtheprocessdoesnotexceeditsmaxdatasize(seesetrlimit(2).sbrkincrementstheprogram'sdataspacebyincrementbytes.sbrkisn'tasystemcall,itisjustaClibrarywrapper.Callingsbrkwithanincrementof0canbeusedtofindthecurrentlocationoftheprogrambreak.RETURNVALUEOnsuccess,brkreturnszero,andsbrkreturnsapointertothestartofthenewarea.Onerror,-1isreturned,anderrnoissettoENOMEM.Sbrk不是系统调用,是C库函数。系统调用通常提供一种最小功能,而库函数通常提供比较复杂的功能。在LirlUX系统上,程序被载入内存时,内核为用户进程地址空间建立了代码段、数据段和堆栈段,在数据段与堆栈段之间的空暇区域用于动态内存分配。内核数据结构mm_struct中的成员变量StarLCOde和end_code是进程代码段的起始和终止地址,Start_data和end_data是进程数据段的起始和终止地址,Start_stack是进程堆栈段起始地址,StarLbrk是进程动态内存分配起始地址(堆的起始地址),还有一个brk(堆的当前最后地址),就是动态内存分配当前的终止地址。C语言的动态内存分配基本函数是malloc(),在LinUX上的基本实现是通过内核的brk系统调用。brk()是一个非常简单的系统调用,只是简单地改变mm_struct结构的成员变量brk的值。mmap系统调用实现了更实用的动态内存分配功能,可以将一个磁盘文件的全部或者部份内容映射到用户空间中,进程读写文件的操作变成为了读写内存的操作。在IinUXmmmmap.c文件的doTImaP_Pgoffo函数,是mm叩系统调用实现的核心。do_mmap_Pgoff()的代码,只是新建了一个vm_area_struct结构,并把file结构的参数赋值给其成员变量mjile,并没有把文件内容实际装入内存。1.inux内存管理的基本思想之一,是惟独在真正访问一个地址的时候才建立这个地址的物理映射。C语言跟内存分配方式(1)从静态存储区域分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量,StatiC变量。(2)在栈上创建。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。(3)从堆上分配,亦称动态内存分配。程序在运行的时候用malloc或者new申请任意多少的内存,程序员自己负责在何时用free或者delete释放内存。动态内存的生存期由我们决定,使用非常灵便,但问题也最多C语言跟内存申请相关的函数主要有alloc,calloc,malloc,free,realloc,Sbrk等.其中alloc是向栈申请内存,因此无需释放.malloc分配的内存是位于堆中的,并且没有初始化内存的内容,因此基本上malloc之后,调用函数memset来初始化这部份的内存空间.calloc则将初始化这部份的内存,设置为0.而realloc则对malloc申请的内存进行大小的调整.申请的内存最终需要通过函数free来释放.而sbrk则是增加数据段的大小;malloc/calloc/free基本上都是C函数库实现的,跟OS无关.C函数库内部通过一定的结构来保存当前有多少可用内存.如果程序malloc的大小超出了库里所留存的空间,那末将首先调用brk系统调用来增加可用空间,然后再分配空间.free时,释放的内存并不即将返回给os,而是保留在内部结构中.可以打个比方:brk类似于批发,一次性的向OS申请大的内存,而malloc等函数则类似于零售,满足程序运行时的要求.这套机制类似于缓冲.使用这套机制的原因:系统调用不能支持任意大小的内存分配(有的系统调用只支持固定大小以及其倍数的内存申请,这样的话,对于小内存的分配会造成浪费;系统调用申请内存代价昂贵,涉及到用户态和核心态的转换.函数malloc()和CallOC()都可以用来分配动态内存空间,但两者稍有区别。malloc()函数有一个参数,即要分配的内存空间的大小:void*malloc(sizejsize);CallOe()函数有两个参数,分别为元素的数目和每一个元素的大小,这两个参数的乘积就是要分配的内存空间的大小:void*calloc(size_tnumElements,size_tSizeOfEIement);如果调用成功,函数malloc()和Calk)C()都将返回所分配的内存空间的首地址。malloc()函数和CalIoC()函数的主要区别是前者不能初始化所分配的内存空间,而后者能。如果由malloc()函数分配的内存空间原来没有被使用过,则其中的每一位可能都是0;反之,如果这部份内存空间曾经被分配、释放和重新分配,则其中可能遗留各种各样的数据。也就是说,使用malloc()函数的程序开始时(内存空间还没有被重新分配)能正常运行,但经过一段时间后(内存空间已被重新分配)可能会浮现问题。calloc()函数会将所分配的内存空间中的每一位都初始化为零,也就是说,如果你是为字符类型或者整数类型的元素分配内存,那末这些元素将保证会被初始化为零;如果你是为指针类型的元素分配内存,那末这些元素通常(但无法保证)会被初始化为空指针;如果你是为实数类型的元素分配内存,那末这些元素可能(只在某些计算机中)会被初始化为浮点型的零。malloc()函数和CalIoC()函数的另一点区别是CalloC()函数会返回一个由某种对象组成的数组,但malloc()函数只返回一个对象。为了明确是为一个数组分配内存空间,有些程序员会选用CalloC()函数。但是,除了是否初始化所分配的内存空间这一点之外,绝大多数程序员认为以下两种函数调用方式没有区别:calloc(numElements,SizeOfEIement);malloc(numElementswSizeOfEIement);需要解样的一点是,理论上(按照ANSlC标准)指针的算术运算只能在一个指定的数组中进行,但是在实践中,即使C编译程序或者翻译器遵循这种规定,许多C程序还是冲破了这种限制。因此,尽管malloc()函数并不能返回一个数组,它所分配的内存空间仍然能供一个数组使用(对realloc()函数来说同样如此,尽管它也不能返回一个数组)。总之,当你在CaliOC()函数和malloc()函数之间作选择时,你只需考虑是否要初始化所分配的内存空间,而不用考虑函数是否能返回一个数组。当程序运行过程中malloc了,但是没有free的话,会造成内存泄漏.一部份的内存没有被使用,但是由于没有free,因此系统认为这部份内存还在使用,造成不断的向系统申请内存,是的系统可用内存不断减少.但是,内存泄漏仅仅指程序在运行时,程序退出时QS将回收所有的资源.因此,适当的重起一下程序,有时候还是有点作用.sbrk(intincr)本函数用来增加分配给调用程序的数据段的空间数量,增加incr个字节的空间brk函数的原形是:intbrk(void*endds)它的功能是:更改数据段空间的分配char*p;p=malloc(1);这时P指向的内存空间大小是1bytebrk(p+100)这时P指向的内存空间大小是101bytes程式分配虚拟内存也不是你要一个字节就给你个字节,而是你要一个字节给你一个页面,因为映射物理内存时只能以页为单位。你要另一个字节时,它在这个页面的剩余空间给你。注意大部份UNIX虚拟内存的使用是只增不减的。CODE:malloc(32*1024)->sbrk+=32*1024free()->sbrk不减少。但如如果再来一次malloc(32*1024)->sbrk也不增,使用原有空间.但对于LlNUX来说它是要以内存的最大数收缩的;CODE:<code>a=malloc(32*1024)->sbrk+=32*1024b=malloc(32*1024)->sbrk+=32*1024if(*)free(b);>sbrk-=32*1024;)elsefree(a);Sbrk不减少。只是多了个空洞.)<code>CODE:<code>*Iinuxkernelcode*/brk()* sys_brk()forthemostpartdoesn'tneedtheglobalkernel* lock,exceptwhenanapplicationisdoingsomethingnasty* liketryingtoun-brkanareathathasalreadybeenmapped* toaregularfile.inthiscase,theunmappingwillneed* toinvokefilesystemroutinesthatneedthegloballock.7asmlinkageunsignedlongsys_brk(unsignedlongbrk)(unsignedlongrlim1retval;unsignedlongnewbrk,oldbrk;structmm_struct*mm=current->mm;down_write(mm->mmap_sem);if(brk<mm->end_code)gotoout;newbrk=PAGE_ALIGN(brk);oldbrk=PAGE_ALIGN(mm->brk);if(oldbrk=newbrk)gotoset_brk;/*虚拟内存在这里收缩*/*Alwaysallowshrinkingbrk.7if(brk<=mm->brk)if(!do_munmap(mm,newbrk,oldbrk-ewbrk)gotoset_brk;gotoout;)Checkagainstrlimit.7rlim=current->rlimRLIMIT_DATA.rlim_cur;if(rlim<RLIM_INFINITY&brk-mm->start_data>rlim)gotoout;Checkagainstexistingmmapmappings.7if(find_vma_intersection(mm,oldbrk,newbrk+PAGE-SIZE)gotoout;Checkifwehaveenoughmemory.7if(!vm_enough_memory(newbrk-oldbrk)>>PAGE-SHIFT)gotoout;*Ok1looksgood-letitrip.7if(do_brk(oldbrk,newbrk-oldbrk)!=oldbrk)gotoout;set_brk:mm->brk=brk;out:retval=mm->brk;/*这就是返回值*/up_write(mm->mmap_sem);returnretval;<code>在LINUX中Sbrk(O)能返回比较精确的虚拟内存使用情况,在Se)LARlS/HP中Sbrk(O)返回以页为单位的虚拟内存使用情况。使用Sbrk(O)来返回程式当前使用了多少内存。<code>main()intstart,end;start=sbrk(O);malloc(*);end=sbrk(O);printf("helloIused%dvmemory,',end-start);brk和Sbrk工作原理sbrkbrksbrk和sbrk主要的工作是实现虚拟内存到内存的映射.在GNUC中,内存分配是这样的:每一个进程可访问的虚拟内存空间为3G,但在程序编译时,不可能也没必要为程序分配这么大的空间,只分配并不大的数据段空间,程序中动态分配的空间就是从这一块分配的。如果这块空间不够,maIloc函数族(realloc,calIoc等)就调用Sbrk函数将数据段的下界挪移,sbrk函数在内核的管理下将虚拟地址空间映射到内存,供malloc函数使用。(参见IinUX内核情景分析)sbrk不是系统调用,是C库函数。系统调用通常提供种最小功能,而库函数通常提供比较复杂的功能。sbrk/brk是从堆中分配空间,本质是挪移一个位置,向后移就是分配空间,向前移就是释放空间,sbrk用相对的整数值确定位置,如果这个整数是正数,会从当前位置向后移若干字节,如果为负数就向前若干字节。在任何情况下,返回值永远是挪移之前的位置在LINUX中Sbrk(O)能返回比较精确的虚拟内存使用情况,比如squid用它来计算内存的使用!在SOLARIS/IIP中Sbrk(O)返回以页为单位的虚拟内存使用情况。使用SbrkS)来返回程式当前使用了多少内存。(fppviewplaincopy1 main()2 intstart,end;3 start=sbrk();4 .5 malloc(*);6 .7 end=sbrk(0);8 printf("helloIused%dvmemory",end-start);9 )brk用绝对的地址指定移到哪个位置。4fppviewplaincopyIO#include<stdio.h>11 #include<unistd.h>12 intmain()13 (14 void*p=sbrk(0);15 int*pl=p;16 brk(pl+4);分配了16个字节的空间17 pl0=10;18 pll=20;19 pl2=30;20 pl3=40;21 pl4=50;22 int*p2=sbrk(4);23 printf("*p2=%dn"j*p2);24 brk(pl+1024);分配整个页面的空间25 brk(pl+512);释放一半空间26 brk(pl);释放所有空间27 )sbrk:参数>o向后挪移当前位置,相当分配内存空间参数<o向前挪移当前位置,相当释放内存空间参数=0当前位置不动>0<0=0返回总是挪移前的位置brk(void*ptr);将当前位置挪移到ptr的位置Ptr的位置普通通过Sbrk(O)获取首地址,然后再计算得出、些Sbrk实例:viewplaincopy28 #include<stdio.h>29 #include<unistd.h>30 intmain()31 (32 *分配1。个字节的空间,返回该空间的首地址*/33 void*=sbrk(12);34 void*p2=sbrk(4);35 void*p3=sbrk(4);36void*p4=sbrk(4);37printf("p=%pn",p);38printf("p2=%pn",p2);39printf("p3=%pn",p3);40printf("p4=%pn",p4);41 *用参数为0来获取未分配空间的开始位置*/42 void*p=sbrk(0);43printf("p=%pn",p0);44 void*p5=sbrk(-4);45printf("p5=%pn",p5);printf("pid=%dn",getpid();sleep(10);/*当释放到一个页面的开始位置时,整个页面会被操作系统回收*/sbrk(-20);/int*pi=p;* pi=10;* (pi+D=20;* (pi+2)=30;* (pi+1023)=123;*(pi+1024)=1024;*/while(l);)#include<stdio.h>#include<unistd.h>Intmain()printf("pid=%dn",getpid();void*=sbrk(0);int*pl=sbrk(4);sleep(10);int*p2=sbrk(1023*4+l);sleep(10);sbrk(-l);while(l);464748495051525354555657585960616263646566676869707172737475)

    注意事项

    本文(brk和sbrk工作原理.docx)为本站会员(夺命阿水)主动上传,课桌文档仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知课桌文档(点击联系客服),我们立即给予删除!

    温馨提示:如果因为网速或其他原因下载失败请重新下载,重复下载不扣分。




    备案号:宁ICP备20000045号-1

    经营许可证:宁B2-20210002

    宁公网安备 64010402000986号

    课桌文档
    收起
    展开