进程加载
前提:基于硬件的语言编写的程序(Java 编写的程序是在虚拟机上运行的 -> 存在一定的出入)
编译
- 定义:
- 编译程序将 ==源代码==(高级语言)编译成处理器可识别的 ==目标代码==
- 编译程序将 ==目标代码== 分割成许多目标代码段,目标代码段被封装形成 ==目标模块==
- 编译程序为每个目标模块分配 ==逻辑地址空间== 然后 ==存放在磁盘== 中
- 细节:
Java
源代码被编译成 字节码 被虚拟机执行 <->C/C++
源代码被编译成 汇编语言 被操作系统执行- 编译程序并不是操作系统的一部分,不同的语言的编译器是不同的:
Java
编译器是javac
;C/C++
编译器是gcc
链接
定义:链接程序将一组目标模块和需要使用的 库函数 链接起来 -> 形成 ==装入模块==(可执行文件 .exe)
解释:比如编写
C/C++
程序时需要使用到编译器内置的函数,链接程序就需要将这些引用的内置函数找到,并且将其和源代码一起封装到目标模块中库函数:
定义:
C/C++
编译器提供的可供程序员直接使用的函数分类:
静态链接库:编译阶段就将使用到的静态库中的函数链接到目标模块中去
动态链接库:进程在运行过程中需要使用时才将动态链接库中函数链接到目标模块中去
(1) 静态链接库不需要被加载到内存中区:因为每个目标模块中已经有需要使用的函数了
(2) 动态链接库必须被加载到内存中去:因为每个目标模块在运行时才会调用相应的函数;所有的进程都可以共享动态链接库:也被称为共享库
区别:
方式:
静态链接:在程序被加载进入内存之前就将程序可能使用到的全部函数链接到目标模块中:
- (1) 程序会相对较大加载进入内存的速度较慢 (2) 占据内存较大
- C/C++ 都是采用这种方式来链接库函数的
装入链接:在程序加载进入内存时就将程序可能使用到的全部库函数链接到目标模块中
动态链接:在进程需要使用到某些库函数时再将需要的库函数链接到目标模块:
- (1) 程序相对较小载入内存速度更快 (2) 节省内存空间
- 系统发现内存没有需要使用的库函数会去磁盘中将其加载到内存中
- Java 和 C++ 中的反射原理就是这样
加载
定义:
加载程序为程序 ==分配合适的物理内存== (内存分配)
加载程序将程序的各个装入模块载入到内存中
分类:
静态加载:程序加载时将所有目标模块全部加载进入内存
全部加载进入内存会使内存的利用率变低:因为并不是所有的目标模块都会被经常使用,如果部分模块不会经常使用,那么加载到内存就是浪费
动态加载:
定义:只有在程序的目标模块 ==被调用时== 才会加载到内存中
解释:进程在执行过程中需要另一个进程,那么调度程序就会检查内存中是否存在,如果不存在就会去磁盘中寻找对应的目标模块,并加载进内存
举例:网页下载资源时,如果迅雷没有开启,那么浏览器会自动帮你打开迅雷,然后使用迅雷下载
细节:内存的利用率会相对较高
解释:软件开发中通常业务核心代码只占据 30% ~ 40%,剩余全是异常处理;显然在程序载入时将这些异常处理都载入进去是不合理的
动态加载 & 动态链接 & 请求调页
地址绑定
定义:加载程序将程序的逻辑地址 ==映射== 到内存中的物理地址 (==地址绑定==)
方式:
编译时绑定:
定义:程序 ==编译阶段== 就将逻辑地址 ==修改== 成物理地址
优点 & 缺点
优点:处理器执行目标代码相对较快
缺点:(1) 进程运行过程中无法再更改其物理地址 (2) 难以提前预知进程在内存中的实际位置
注:如果想要修改程序在内存中的地址只能够 ==重编译==
处理器使用过程:
- 调度程序交付给处理器进程的入口地址(逻辑地址)
- 处理器将 ==逻辑地址== 和 ==基地址 & 界限地址== 进行比较
- 如果超出地址界限 -> 寻址错误造成操作系统陷入
- 如果没有超出地址界限 -> 处理器就可以正常访问进程在内存中的位置
加载时绑定:
定义:程序加载进入内存时就确定逻辑地址和物理地址的映射关系(关系确立好了显然就是不能改的了)
优点 & 缺点:
优点:不需要硬件支持
缺点:(1) 进程运行过程中无法再更改其物理地址
注:想要修改程序在内存中的位置只能够 ==重启== 进程
运行时绑定:
定义:进程被调度执行时才确定逻辑地址和物理地址的映射关系
解释:程序被载入内存中并不一定立刻执行,只有当处理器真的需要执行这个进程的时候,才确定逻辑地址和物理地址的映射关系
优点 & 缺点
缺点:需要硬件提供支持 -> 需要提供 内存管理单元(MMU)
注:内存管理单元就是用于保存逻辑地址到物理地址映射的硬件 -> 之后的页表寄存器,转换表缓冲区…都设置在这里面
处理器使用过程:
- 调度程序交付给处理器进程的入口地址(逻辑地址)
- 处理器将 ==逻辑地址== 交付给 ==内存管理单元(MMU)==
- 内存管理单元将 ==逻辑地址映射到物理地址== (…)
- 处理器正常访问到进程在内存中的位置