进程加载进化史与虚拟内存
Posted zzfx
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了进程加载进化史与虚拟内存相关的知识,希望对你有一定的参考价值。
程序加载的本质是:将可执行文件加载进内存,以供CPU调用执行。
原始加载:
在早期的计算机中,程序是直接运行在物理内存上的,程序在运行时访问的地址就是物理地址。
假设我们计算有128MB内存,程序A需要10MB,程序B需要100MB,程序C需要20MB。如果我们需要同时运行程序A和B,那么比较直接的做法是将内存的前10MB分配给程序A,10MB~110MB分配给B。
但这样做,地址空间不隔离,内存使用效率低,程序运行的地址不确定。
原始加载就是将可执行文件全部加载进内存,以完成进程任务。
原始加载存在的问题:
1)程序的地址不是从0开始,有违于人们的思维习惯。
2)内存不足。
第一次进化:动态装入
用于解决内存不足的问题。
程序执行时所需要的指令和数据必须在内存中才能够正常运行。当然,最简单的办法就是将程序运行所需要的全部资源全部装入内存。但是这样会造成内存的浪费。研究发现程序运行是有局部性原理的,所以比较好的解决方法就是将程序最常用的部分驻留在内存中,而将一些不太常用的数据存放在磁盘里,这就是动态装入 的基本原理。
覆盖装入 (Overlay)和页映射 (Paging)是两种典型的动态装载方法,它们都利用了程序的局部性原理。动态装入的基本思想就是用到哪个模块就将哪个模块装入内存,如果用不到则暂时不装入,存放到磁盘。
覆盖装入
覆盖装入的方法把挖掘内存潜力的任务交给了程序员,程序在编写时必须手工分割成若干块,然后编写一个小的辅助代码来管理这些模块何时应该驻留内存,何时应该被替换掉。这个小的辅助代码就是所谓的覆盖管理器(Overlay Manager)。
程序员需要手工将模块按照它们之间的调用依赖关系组织成树状结构。覆盖管理器,保证某个模块被调用时,整个调用路径上的模块都在内存中
页映射(Paging)
页映射是将内存和所有磁盘中的数据和指令按照“页”为单位划分成若干个页,以后所有的装载和操作的单位就是页。利用换入换出机制(如FIFO,LUR等)即可完成。
第二次进化:
安全与共享控制
http://blog.csdn.net/cc_net/article/details/24726287
分页实际是一个纯粹逻辑上的概念,因为实际的程序和内存并没有被真正的分为了不同的页面。而分段则不同,他是一个逻辑实体。一个段中可以是变量,源代码或者堆栈。一般来说每个段中不会包含不同类型的内容。而分段主要有以下几个作用:
- 解决编译问题: 前面提到过在编译时地址覆盖的问题,可以通过分段来解决,从而简化编译程序。
- 重新编译: 因为不同类型的数据在不同的段中,但其中一个段进行修改后,就不需要所有的段都重新进行编译。
- 内存共享: 对内存分段,可以很容易把其中的代码段或数据段共享给其他程序,分页中因为数据代码混合在一个页面中,所以不便于共享。
- 安全性: 将内存分为不同的段之后,因为不同段的内容类型不同,所以他们能进行的操作也不同,比如代码段的内容被加载后就不应该允许写的操作,因为这样会改变程序的行为。而在分页系统中,因为一个页不是一个逻辑实体,代码和数据可能混合在一起,无法进行安全上的控制。
- 动态链接: 动态链接是指在作业运行之前,并不把几个目标程序段链接起来。要运行时,先将主程序所对应的目标程序装入内存并启动运行,当运行过程中又需要调用某段时,才将该段(目标程序)调入内存并进行链接。可见,动态链接也要求以段作为管理的单位。
- 保持兼容性
所以在现在的x86的体系结构中分段内存管理是必选的,而分页管理则是可选的。
缺点:进程必须全部装入内存。
第三次进化:段页式管理与虚拟内存
段页式内存管理
http://blog.csdn.net/cc_net/article/details/24726287
分段内存管理的优势在于内存共享和安全控制,而分页内存管理的优势在于提高内利用率。他们之间并不是相互对立的竞争关系,而是可以相互补充的。也就是可以把2种方式结合起来,也就是目前计算机中最普遍采用的段页式内存管理。段页式管理的核心就是对内存进行分段,对每个段进行分页。这样在拥有了分段的优势的同时,可以更加合理的使用内存的物理页。
以上是关于进程加载进化史与虚拟内存的主要内容,如果未能解决你的问题,请参考以下文章