




已阅读5页,还剩45页未读, 继续免费阅读
版权说明:本文档由用户提供并上传,收益归属内容提供方,若内容存在侵权,请进行举报或认领
文档简介
虚拟内存是用户实际使用计算机时所面对的内存,它并不是实际的内存,而是由内存和外存共同抽象出来的内存。用户在使用Linux系统的时候,所进行的操作都是针对虚拟内存而来的。在Linux中,所有的进程都存在于各自独立的内存地址空间中。对于每个进程所拥有的独立内存空间,依次由以下几个部分所组成:程序代码区、全局数据区(清零区)、堆区、栈区、内核空间(详见P163)。,Linux的内存管理,进程的地址空间linux采用虚拟内存管理技术,段页式内存分配,每一个进程都有一个3G大小的独立的进程地址空间,和共享的1G内核内存空间。这个地址空间就是用户空间。每个进程的用户空间都是完全独立、互不相干的。进程访问内核空间的方式:系统调用和中断。,Linux的内存管理,创建进程等进程相关操作都需要分配内存给进程。这时进程申请和获得的不是物理地址,仅仅是虚拟地址。实际的物理内存只有当进程真去访问新获取的虚拟地址时,才会由“请页机制”产生“缺页”异常,从而进入分配实际页框的程序。该异常是虚拟内存机制赖以存在的基本保证,它会告诉内核去为进程分配物理页,并建立对应的页表,这之后虚拟地址才实实在在的映射到了物理地址上。,Linux的内存管理,Linux的内存管理,伙伴算法Linux内核内存管理的任务包括:遵从CPU的MMU(MemoryManagementUnit)机制合理、有效、快速地管理内存实现内存保护机制实现虚拟内存共享重定位,Linux的内存管理,Linux内核通过伙伴算法来管理物理内存。伙伴系统(BuddySystem)在理论上是非常简单的内存分配算法。它的用途主要是尽可能减少外部碎片,同时允许快速分配与回收物理页面。为了减少外部碎片,将连续的空闲页面,根据空闲块(由连续的空闲页面组成)大小,组织成不同的链表(或者orders)。这样所有的2个页面大小的空闲块在一个链表中,4个页面大小的空闲块在另外一个链表中,以此类推。,Linux的内存管理,Linux的内存管理,注意,不同大小的块在空间上,不会有重叠。当一个需求为4个连续页面时,检查是否有4个页面的空闲块而快速满足请求。若该链表上(每个结点都是大小为4页面的块)有空闲的块,则分配给用户,否则向下一个级别(order)的链表中查找。若存在(8页面的)空闲块(现处于另外一个级别的链表上),则将该页面块分裂为两个4页面的块,一块分配给请求者,另外一块加入到4页面的块链表中。这样可以避免分裂大的空闲块,而此时有可以满足需求的小页面块,从而减少外面碎片。,Linux的内存管理,Linux的内存管理,伙伴算法举例假设我们的系统内存只有16个页面RAM。因为RAM只有16个页面,我们只需用四个级别(orders)的伙伴位图(因为最大连续内存大小为16个页面),如后图所示,Linux的内存管理,Linux的内存管理,在order(0),第一个bit表示开始的2个页面,第二个bit表示接下来的2个页面,以此类推。因为页面4已分配,而页面5空闲,故第三个bit为1,同理第六个bit为1。,Linux的内存管理,同样在order(1)中,bit3是1的原因是一个伙伴完全空闲(页面8和9),和它对应的伙伴(页面10和11)却并非如此,故以后回收页面时,可以合并。,Linux的内存管理,分配过程当我们需要order(1)的空闲页面块时,则执行以下步骤:1、初始空闲链表为:order(0):5,10order(1):88,9order(2):1212,13,14,15order(3):,Linux的内存管理,2、从上面空闲链表中,我们可以看出,order(1)链表上,有一个空闲的页面块8,9,把它分配给用户,并从该链表中删除。3、当我们再需要一个order(1)的块时,同样我们从order(1)空闲链表上开始扫描。4、若在order(1)上没有空闲页面块,那么我们就到更高的级别(order)上找,order(2)。,Linux的内存管理,5、此时有一个空闲页面块,该块是从页面12开始。该页面块被分割成两个稍微小一些order(1)的页面块,12,13和14,15。14,15页面块加到order(1)空闲链表中,同时12,13页面块分配给用户。,Linux的内存管理,6、最终空闲链表为:order(0):5,10order(1):1414,15order(2):order(3):,Linux的内存管理,回收过程当我们回收页面11(order0)时,则执行以下步骤:1、找到在order(0)伙伴位图中代表页面11的位,计算使用下面公式:index=page_idx(order+1)=11(0+1)=5/10111=0101,Linux的内存管理,2、检查上面一步计算位图中相应bit的值。若该bit值为1,则和我们临近的,有一个空闲伙伴。Bit5的值为1(注意是从bit0开始的,Bit5即为第6bit),因为它的伙伴页面10是空闲的。3、现在我们重新设置该bit的值为0,因为此时两个伙伴(页面10和页面11)完全空闲。4、我们将页面10,从order(0)空闲链表中摘除。5、此时,我们对2个空闲页面(页面10和11,order(1)进行进一步操作。,Linux的内存管理,6、新的空闲页面是从页面10开始的,于是我们在order(1)的伙伴位图中找到它的索引,看是否有空闲的伙伴,以进一步进行合并操作。使用第一步中的计算公式,我们得到bit2(第3位)(10102)。7、Bit2(order(1)位图)同样也是1,因为它的伙伴页面块(页面8和9)是空闲的。8、重新设置bit2(order(1)位图)的值,然后在order(1)链表中删除该空闲页面块。,Linux的内存管理,9、现在我们合并成了4页面大小(从页面8开始)的空闲块,从而进入另外的级别。在order(2)中找到伙伴位图对应的bit值,是bit1(10003),且值为1,需进一步合并(原因同上)。10、从order(2)链表中摘除空闲页面块(从页面12开始),进而将该页面块和前面合并得到的页面块进一步合并。现在我们得到从页面8开始,大小为8个页面的空闲页面块。,Linux的内存管理,11、进入另外一个级别,order(3)。它的位索引为0,它的值同样为0。这意味着对应的伙伴不是全部空闲的,所以没有再进一步合并的可能。我们仅设置该bit为1,然后将合并得到的空闲页面块放入order(3)空闲链表中。12、最终我们得到大小为8个页面的空闲块:,Linux的内存管理,Linux的内存管理,用户空间:(1)从静态存储区域(清零区)分配。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量,static变量。(2)在栈上创建(向低地址增长)。在执行函数时,函数内局部变量的存储单元都可以在栈上创建,函数执行结束时这些存储单元自动被释放。栈内存分配运算内置于处理器的指令集中,效率很高,但是分配的内存容量有限。,Linux的内存管理,(3)从堆上分配,亦称动态内存分配(向高地址增长)。程序在运行的时候用malloc或new申请任意多少的内存,程序员自己负责在何时用free或delete释放内存。动态内存的生存期由应用决定,使用非常灵活。(4)程序代码区。用户空间的开始部分,只读,存放进程代码。,Linux的内存管理,动态申请的函数,在堆上分配。mallco/free:不初始化,返回一个对象。calloc/free:初始化为0,返回对象的数组。realloc:对malloc申请的内存进行大小的调整。alloca:在栈上申请内存。void*memalign(size_tboundary,size_tsize)申请较大的内存块,空间颗粒大些,boundary为2的幂。valloc:分配的内存与页边界对齐。void*valloc(size_tsize)returnmemalign(getpagesize(),size);关于各类分配函数,详见“内存分配函数.doc”关于物理内存分配,详见“物理空间.doc”、“slab算法”等文档,Linux的内存管理,sbrk/brk:是增加数据段的大小。malloc/calloc/free基本上都是C函数库实现的,跟OS无关。C函数库内部通过一定的结构来保存当前有多少可用内存。如果程序malloc的大小超出了库里所留存的空间,那么将首先调用sbrk系统调用来增加可用空间,然后再分配空间(释放空间也是释放到结构)。,Linux的内存管理,内核空间:,Linux的内存管理,直接映射区:线性空间中从3G开始,不超过896M的区间,为直接内存映射区(Kmalloc),该区域物理空间连续,线性地址和物理地址存在线性转换关系:线性地址=3G+物理地址。动态映射区:该区域由内核函数vmalloc来分配,特点是:虚拟线性空间连续,但是对应的物理空间不一定连续。vmalloc分配的线性地址所对应的物理页可能处于低端内存,也可能处于高端内存。,Linux的内存管理,永久映射区:该区域可访问高端内存。访问方法是使用alloc_page(_GFP_HIGHMEM)分配高端内存页或者使用kmap函数将分配到的高端内存映射到该区域。固定映射区:该区域和4G的顶端只有4k的隔离带,其每个地址项都服务于特定的用途,如ACPI_BASE等。,Linux的内存管理,kmalloc/kfree:申请小块内存,物理地址连续,如一些通用对象,使用slab分配。管理从3G到vmalloc_start(最大896M,该区域中包含了内核镜像、物理页框表mem_map等等)。get_free_page/free_page;virt_to_phys/phys_to_virt;,Linux的内存管理,vmalloc/vfree:仅在绝对必要时才会使用,最典型的就是为了获得大块内存时,例如,当模块被动态插入到内核中时,就把模块装载到由vmalloc()分配的内存上。管理从VMALLOC_START4GB的空间;为了把物理上不连续的页面转换为虚拟地址空间上连续的页,必须专门建立页表项。还有,通过vmalloc()获得的页必须一个一个的进行映射(因为它们物理上不是连续的,慢。),Linux的内存管理,内存函数:bcopy、bzero和bcmp是传统BSD的函数,属于POSIX标准,是在linux下的函数;mem*是C90(以及C99)标准的C函数。区别在于,如果你打算把程序弄到一个符合C90/C99,但是不符合POSIX标准的平台时,后者比较有优势。NetBSD的代码中有很多地方使用mem*(他们更偏爱mem*,以利于移植),即使内核也是如此,而FreeBSD的内核中则尽量避免使用(希望尽可能避免在内核中出现较多的C函数)。如果你提交代码的话需要注意这些约定,Linux的内存管理,bcopy和memcpy、bzero和memset、bcmp和memcmpmemset:是对字节进行操作原型:void*memset(void*s,charch,unsignedn);功能:将s所指向的某一块内存中的每个字节的内容全部设置为ch指定的ASCII值。即将指定的内存,以字节为单位,置为ch所代表的内存形式。块的大小由第三个参数指定,这个函数通常为新申请的内存做初始化工作。,Linux的内存管理,原理:以字节为单位复制内存的二进制形式,到指定的内存区域。(注:第二个数字也可以是int型,然后截取该int变量的最低字节。作为复制的二进制模板。所以第二个字节最常见的是0全部置零或-1全部置1。)用途:memset最常见的用途是对struct做初始化工作memset(结构体的地址,0,sizeof(结构体));,Linux的内存管理,bzero:将以地址s开头的的前n个字节为零。原型:voidbzero(void*s,intn);说明:bzero无返回值。bzero只能在linux下调用。,Linux的内存管理,memcpy:用来做内存拷贝,你可以拿它拷贝任何数据类型的对象,可以指定拷贝的数据长度。原型:void*memcpy(void*dest,void*src,unsignedintcount);功能:由src所指内存区域复制count个字节到dest所指内存区域。说明:src和dest所指内存区域不能重叠,函数返回指向dest的指针,Linux的内存管理,memccpy:由src所指区域复制不多于count个字节到dest所指内存区域,如果遇到字符ch则停止复制。原型:void*memccpy(void*dest,void*src,unsignedcharch,unsignedintcount);说明:返回指向字符ch后的第一个字符的指针,如果src前n个字节中不存在ch则返回NULL。,Linux的内存管理,strcpy:只能拷贝字符串,它遇到0就结束拷贝。原型:char*strcpy(char*dest,char*src);功能:把src所指由NULL结束的字符串复制到dest所指的数组中。说明:src和dest所指内存区域不可以重叠且dest必须有足够的空间来容纳src的字符串。,Linux的内存管理,bcopy:将字符串src的前n个字节复制到dest中.原型:voidbcopy(constvoid*src,void*dest,intn)说明:bcopy不检查字符串中的空字节NULL,函数没有返回值。目标和源的位置与memcpy和strcpy不同。,Linux的内存管理,memcmp:比较内存区域buf1和buf2的前count个字节。原型:intmemcmp(void*buf1,void*buf2,unsignedintcount);说明:当buf1buf2时,返回值0,Linux的内存管理,bcmp:比较字符串s1和s2的前n个字节是否相等原型:intbcmp(constvoid*s1,constvoid*s2,intn);说明:如果s1=s2或n=0则返回零,否则返回非零值。bcmp不检查NULL。,Linux的内存管理,memmove:由src所指内存区域复制count个字节到dest所指内存区域。原型:void*memmove(void*dest,constvoid*src,unsignedintcount);说明:src和dest所指内存区域可以重叠,但复制后src内容会被更改。函数返回指向dest的指针。,Linux的内存管理,memchr:从buf所指内存区域的前count个字节查找字符ch。原型:void*memchr(void*buf,charch,unsignedcount);说明:当第一次遇到字符ch时停止查找。如果成功,返回指向字符ch的指针;否则返回NULL。,Linux的内存管理,mmap系统调用阅读文件“关于mmap函数.doc”。,Linux的内存管理,注:实际上,mmap()系统调用并不是完全为了用于共享内存而设计的。它本身提供了不同于一般对普通文件的访问方式,进程可以像读写内存一样对普通文件的操作。而Posix或系统V的共享内存IPC则纯粹用于共享目的,当然mmap()实现共享内存也是其主要应用之一。,Linux的内存管理,设备操作mmap操作提供了一种机制,让用户程序直接访问设备内存,这种机制,相比较在用户空间和内核空间
温馨提示
- 1. 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。图纸软件为CAD,CAXA,PROE,UG,SolidWorks等.压缩文件请下载最新的WinRAR软件解压。
- 2. 本站的文档不包含任何第三方提供的附件图纸等,如果需要附件,请联系上传者。文件的所有权益归上传用户所有。
- 3. 本站RAR压缩包中若带图纸,网页内容里面会有图纸预览,若没有图纸预览就没有图纸。
- 4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
- 5. 人人文库网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对用户上传分享的文档内容本身不做任何修改或编辑,并不能对任何下载内容负责。
- 6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
- 7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。
最新文档
- 2025年智慧港口自动化装卸设备智能化改造方案与实施路径报告
- 2025呼伦贝尔农垦那吉屯农牧场招聘考试练习附答案详解(考试直接用)
- 2025年教师招聘之《小学教师招聘》题库必刷100题含答案详解ab卷
- 2025党章党规党纪知识考试题及参考答案
- 押题宝典教师招聘之《幼儿教师招聘》通关考试题库及参考答案详解(达标题)
- 教师招聘之《幼儿教师招聘》考前冲刺模拟题库提供答案解析及参考答案详解(研优卷)
- 教师招聘之《幼儿教师招聘》模拟考试高能及参考答案详解(培优b卷)
- 幼儿园贫困生资助自查报告
- 教师招聘之《小学教师招聘》通关模拟题库附答案详解(基础题)
- 教师招聘之《小学教师招聘》每日一练往年题考附答案详解
- 2025台州路桥区公开招聘中小学教师40人考试参考试题及答案解析
- 2025-2026学年人美版(2024)小学美术三年级上册教学计划及进度表
- 2024-2025学年广东省汕头市金平区七年级(下)期末数学试卷
- 2025版家居用品定制加工合作协议
- 居家养老安全培训内容
- 2025-2026学年人教版(2024)初中体育与健康七年级全一册教学计划及进度表(第一学期)
- 2025-2026学年济南版(2024)初中生物八年级上册教学计划及进度表
- “一带一路”倡议下的企业出海战略研究
- 体系管理知识培训课件
- 辽宁沈阳地铁有限公司所属公司招聘笔试题库完整参考答案详解
- 2025年秋季小学二年级上册语文教学计划及教学进度表
评论
0/150
提交评论