- 进程之间地址空间不隔离
- 多进程时, 内存碎片多(分页), 内存利用效率低(缓存命中率)
- 程序运行的地址空间不确定
提高缓存命中率
读写权限隔离
提高内存利用效率(多个运行的线程可以共享一份代码段)
提高内存利用率,减少内存碎片
和虚拟内存管理机制一起解决了内存不连续的问题(分配的内存一般是虚拟内存,在第一次使用虚拟内存发生缺页中断中才会真正分配物理内存)
Linux 下线程与进程都是使用同一个结构体task_struct来表示的,线程之间共享的内存结构来区分线程和进程之间的并发程度,内核线程 复制阻塞情况下的线程切换, 非阻塞的线程切换在用户态处理。
Stack
寄存器
线程局部存储
.o 可重定位文件 有一个重定位表 rel.text 用于重定位符号
可执行文件
.so 共享目标文件,用于动态链接
BSS 未初始化的静态变量
COMMON 未初始化的全局变量(因为暂时不知道需要多少内存)
DATA 初始化的全局变量的静态变量
TEXT
RODATA
符号表(重定位和符号决议)
文件头 版本 大小 偏移量 magic number
重定位表 前置声明的重定位
前置声明是弱符号, 定义/初始化是强符号,在副号决议的时候会优先对应强符号,多个强符号会报错冲突。
C++的重载 对符号名的影响
命名空间 对符号名的影响
函数声明规范
函数,变量的 外连接性质
- 扫描输入目标文件获得各个段的长度,分配内存并维护一个全局符号表
- 根据全局符号表和重定位表 完成副号决议 和 重定位
初始化进程环境,堆分配初始化,传递main 的参数,全局变量的初始化等。
.init 段:
.fini 段:
32位平台下的4G内存空间,1GB内核,1GB用户态。
页映射是虚拟存储机制的一部分,随着虚拟存储的发明而诞生,数据和指令按页划分完毕后装载,如果程序使用物理地址直接进行操作,那么每次装入页都要进行重定位。
创建一个独立的虚拟地址空间(分配一个页目录)
建立空间和可执行文件的映射关系(进程中VMA映射到ELF的.text段)
CPU寄存器设置为可执行文件入口地址
把相同权限的段合并在一起映射
原文:https://www.cnblogs.com/joeylee97/p/9169099.html