进程加载进化史与虚拟内存

程序加载的本质是:将可执行文件加载进内存,以供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

分页实际是一个纯粹逻辑上的概念,因为实际的程序和内存并没有被真正的分为了不同的页面。而分段则不同,他是一个逻辑实体。一个段中可以是变量,源代码或者堆栈。一般来说每个段中不会包含不同类型的内容。而分段主要有以下几个作用:

  1. 解决编译问题: 前面提到过在编译时地址覆盖的问题,可以通过分段来解决,从而简化编译程序。
  2. 重新编译: 因为不同类型的数据在不同的段中,但其中一个段进行修改后,就不需要所有的段都重新进行编译。
  3. 内存共享: 对内存分段,可以很容易把其中的代码段或数据段共享给其他程序,分页中因为数据代码混合在一个页面中,所以不便于共享。
  4. 安全性: 将内存分为不同的段之后,因为不同段的内容类型不同,所以他们能进行的操作也不同,比如代码段的内容被加载后就不应该允许写的操作,因为这样会改变程序的行为。而在分页系统中,因为一个页不是一个逻辑实体,代码和数据可能混合在一起,无法进行安全上的控制。
  5. 动态链接: 动态链接是指在作业运行之前,并不把几个目标程序段链接起来。要运行时,先将主程序所对应的目标程序装入内存并启动运行,当运行过程中又需要调用某段时,才将该段(目标程序)调入内存并进行链接。可见,动态链接也要求以段作为管理的单位。
  6. 保持兼容性

所以在现在的x86的体系结构中分段内存管理是必选的,而分页管理则是可选的。

缺点:进程必须全部装入内存。

第三次进化:段页式管理与虚拟内存

段页式内存管理

http://blog.csdn.net/cc_net/article/details/24726287

分段内存管理的优势在于内存共享和安全控制,而分页内存管理的优势在于提高内利用率。他们之间并不是相互对立的竞争关系,而是可以相互补充的。也就是可以把2种方式结合起来,也就是目前计算机中最普遍采用的段页式内存管理。段页式管理的核心就是对内存进行分段,对每个段进行分页。这样在拥有了分段的优势的同时,可以更加合理的使用内存的物理页。

时间: 2025-01-08 15:11:04

进程加载进化史与虚拟内存的相关文章

进程加载进化史(进程加载与内存存贮管理)

http://blog.sina.com.cn/s/blog_6f5e19860102vlv0.html 存储管理的基本原理 内存管理方法 内存管理主要包括内存分配和回收.地址变换.内存扩充.内存共享和保护等功能. 下面主要介绍连续分配存储管理.覆盖与交换技术以及页式与段式存储管理等基本概念和原理. 1.连续分配存储管理方式 连续分配是指为一个用户程序分配连续的内存空间.连续分配有单一连续存储管理和分区式储管理两种方式. (1)单一连续存储管理 在这种管理方式 中,内存被分为两个区域:系统区和用

手把手教你R0下通过EPROCESS获取进程加载模块

在R3下获取一个进程加载的相关模块儿还是比较简单的,直接通过ToolHelp32库API就能够获取到进程关联的模块儿了,但是既然已经在R0下混了再去使用R3层的东西就没什么意义了,所以这里小悠在这里将会一部一部的介绍如何在R0下通过EPROCESS结构获取到进程加载的模块. 首先这里我们先介绍一下我们通过EPROCESS查询的大概思路 ①  通过EPROCESS 获取到对应的PEB 结构 ②  通过PEB找到 _PEB_LDR_DATA这货 ③  在_PEB_LDR_DATA内部有3个LIST_

Linux进程2——进程加载

Linux每个可执行程序都具有相同的虚拟地址分配,当OS启动进程时,是如何加载程序呢? 1. 进程结构体 每个进程都具有task_struct结构体,该结构体的mm字段负责对程序内存的虚拟地址映射. mm中每个vm_area_struct对应可执行程序的段虚拟地址空间,例如.text等.当程序被执行时,程序的这些虚拟地址 就被填入不同的vm_area_struct中. struct vm_area_struct { ... ... unsigned long vm_start; //虚拟地址开始

Android获取其他进程加载的模块基地址

获取目标进程模块(.so)加载地址是通过解析/proc/[pid]/maps得到的. 可以通过adb shell手动获取: ①. 首先通过ps命令查看进程的pid ②. cat /proc/[pid]/maps 使用程序实现如下代码: #include <stdio.h> int main(int argc, char* argv[]) { if (argc != 3) { printf("pid or soName error\r\n"); return 1; } pid

android so加载

本文分析so加载的步骤,其实在之前dalvik浅析二中也有提及,但那重点关注的是jni.android中so库的加载,代码如下: loadLibrary("nanosleep"); 我们来看下它的执行流程吧: 先调用dlopen来载入so文件:find_library在soinfo结构(进程加载的so链)中查找当前so是否已载入,否则去执行so载入流程.so载入后,find_library会返回soinfo,去执行so的CallConstructors函数:如果so包含init.ini

Windows Phone 8加载外部动态链接库DLL(非安装包内的)

Windows Phone 8加载外部动态链接库DLL(非安装包内的) 在<动态加载与插件化>中大概介绍了下,wp8加载非安装包的下动态链接库,这次详细梳理下. 加载外部DLL主要的原理: 通过NtCurrentTeb获得线程环境块 从线程环境块中获得进程环境块 在进程环境块中加载过得DLL链表 从链表中找到kernelbase.dll的模块句柄 从kernelbase.dll中获得LoadLibraryEx函数地址 加载指定地址下的DLL 相关的结构体: typedef struct _CL

Chromium插件(Plugin)模块(Module)加载过程分析

在Chromium中,每一个Plugin都对应一个Module,称为Plugin Module.一个Plugin Module可创建多个Plugin Instance.每一个Plugin Instance对应于网页中的一个<embed>标签.在为<embed>标签创建Plugin Instance之前,先要加载其对应的Plugin Module.本文接下来分析Plugin Module的加载过程. 老罗的新浪微博:http://weibo.com/shengyangluo,欢迎关注

Android WebView加载Chromium动态库的过程分析

Chromium动态库的体积比较大,有27M左右,其中程序段和数据段分别占据25.65M和1.35M.如果按照通常方式加载Chromium动态库,那么当有N个正在运行的App使用WebView时,系统需要为Chromium动态库分配的内存为(25.65 + N x 1.35)M.这是非常可观的.为此,Android使用了特殊的方式加载Chromium动态库.本文接下来就详细分析这种特殊的加载方式. 老罗的新浪微博:http://weibo.com/shengyangluo,欢迎关注! 为什么当有

World Wind Java开发之十五——加载三维模型

之前的一篇博客是关于加载粗三维模型的,见http://blog.csdn.net/giser_whu/article/details/43452703,这个地方还存在着不能加载纹理的问题,一直没呢解决.那么WW如何加载常用的三维模型格式(3ds.obj.skp)呢,通过一番搜索,了解到WW可以加载collada的dae格式的三维模型,并且还可以加载kml\kmz文件,那么WW加载三维模型的方法就出来了:首先将其他格式三维模型转换为kmz或kml文件,再加载.这里我是从su的三维模型库中下载的sk