linux 内存管理浅析(二)

来源:互联网 发布:淘宝蜗牛的潘多拉真吗 编辑:程序博客网 时间:2024/04/29 10:51
上讲中,讲解了linux的物理内存管理,这讲进行虚拟内存管理的讲解。
       我们程序猿们经常讲“我new(malloc)了多少内存”,实际上我们使用的new(malloc)申请的内存是“虚拟内存”,更确切的说,我们程序猿(app程序猿,不是写内核的)所能操控的都是“虚拟内存”。
       什么是“虚拟内存”?就是这个“内存”不是指真正内存条的,而是操作系统给你开的一个空头支票。尼玛?这是怎么回事?是不是有点晕?没事,我给大家举个例子。
       假设有个银行,银行只有1000w,谁需要钱就向银行借,后续只需还本金不用还利息(现实中要有这么好就好了)。假设每个人一生下来,银行就给他开个1000w的支票且不能直接使用支票,但银行并不会马上给他1000w,等到他用钱的时候,银行就给他实际需要的数目,如果银行暂时没有那么多,就让他等等。但是一般人都不会一次性需要那么多钱,这样基本上每个人取钱的时候,银行一般都会满足,让每个人感觉他都有1000w可用。
       操作系统就好像上面例子中的银行,物理内存就好像钱,虚拟内存就是银行开出的支票。当我们app启动时,操作系统就分给它4G虚拟内存(32位),等到app实际需要内存时,操作系统才分配真正的物理内存给它,这样每个app都感觉它拥有4G内存。
       为什么要有虚拟内存呢?
       我的理解是:方便管理,安全。
       如果每个app直接去操作物理内存,由于只有一块物理内存,那每个程序起始的物理地址就不一样,比较麻烦,有了虚拟内存,大家的起始地址都一样,方便管理;再就是安全,有了虚拟内存,app只能操作虚拟内存,物理内存由内核统一安排,这样不至于某个app出了问题,把别的app的内存数据给覆盖,影响另一个app。
        现在应该看看虚拟内存的地址空间了(32位的):
虚拟地址空间.jpg


        虚拟地址空间总体上分为两大部分:内核空间(1G)和用户空间(3G)。我们的app能操作的虚拟地址就是用户空间部分。
       内核空间:内核空间大体上又可分为两部分,3G~3G+896M,这部分到物理地址的映射是写死的,毕竟总得有内核自己的代码也是要加载到物理内存中才能执行啊!(这也说明,程序中的初始化是一个程序非常重要的部分,今后遇到开源程序,先看它的初始部分,否则会看晕的)
       用户空间:用户空间一般有3G,又可细分为:stack、mmap、heap、bss、data、text等部分。
       stack:比较常见,就是我们平时说的栈,内存的释放不需要我们管理;
       mmap:这里一般是将我们要读的文件映射进来,实现文件的直接读写;
       heap:就是我们平常说的堆, c/c++中的new、malloc就是在这个范围内分配,需要我们程序管理释放。
       bss:通常是指用来存放程序中未初始化的全局变量的一块内存区域。
       data:通常是指用来存放程序中已初始化的全局变量的一块内存区域。
       text:通常是指用来存放程序执行代码的一块内存区域。
       用户空间的这些划分都是逻辑上的,内核代码中使用memory region对象实际管理整个虚拟地址空间,结构为vm_area_struct。一个进程中可能有多个memory region,每个memory region代表了一段地址空间范围。所有memory region以链表的形式连接在一起(同时也以红黑树的结构存储,为了快速定位一个具体的地址)。
       memory region和上面将的stack、heap等是模糊对应的,例如bss、heap等有可能在同一个memory region上。

       讲到这里,基本上把虚拟内存与物理内存的关系,以及虚拟内存的作用将清楚了(有不清楚的,可以下来直接找我)。现在就应该讲讲内核中是怎么把虚拟内存映射到物理内存的(毕竟支票无法使用)。
       经过编译后的程序中的地址都是虚拟地址,cpu再执行这个命令之前必须把虚拟地址转换为物理地址,这个转换使用的就是页表,每个app都有自己的页表。linux为了高度抽象化,规定页表有四级:
       页全局目录PGD、页上级目录PUD、页中间目录PMD和页表PT。如下图所示:(具体转换不做介绍,网上比较多,大家可以查阅)
15249652_2.jpg


        讲到这里,大家似乎感觉到:一个程序要使用内存,必须先申请虚拟内存,然后操作系统才给你分配物理内存。you are right!!!程序中分配虚拟内存的接口为new(c++)、malloc(c)。java中不需要我们自己操作,是由jvm向操作系统申请的。
        本贴只将了基本性的概念,具体大家可以分块查询,学习。
0 0
原创粉丝点击