虚拟内存视角下的Linux进程 & 动态内存分配
Linux的虚拟内存系统
Linux为每个进程提供了一个虚拟地址空间。而这些地址空间被分为两部分:
- 进程虚拟内存部分
- 内核虚拟内存部分
进程虚拟内存部分我们已经很熟悉了,按照地址从低到高,他们分别是:
用户栈 | |
---|---|
%rsp → | |
共享库的内存映射区域 | |
brk → | |
运行时的堆(通过malloc分配的) | |
未初始化的数据(.bss) | |
已初始化的数据(.data) | |
0x400000 → | 代码(.text) |
内核虚拟内存可分为两部分:
- 内核中的代码和数据及数据结构
- 被映射到此的物理内存(Linux将一组连续的虚拟内存(大小等于系统DRAM总量)映射到物理内存,为内核提供一种便利的方法来访问物理内存中的任何位置)
与进程相关的数据结构(页表、task和mm结构、内核栈) | 每个进程都不相同 |
---|---|
物理内存 | 每个进程都相同 |
内核代码和数据 | 每个进程都相同 |
Linux如何组织虚拟内存
Linux将虚拟内存组成成一些区域的集合。一个区域就是已分配的虚拟内存片段
这些片段通过一个结构链表被组织起来。(task_struct->mm_struct->mmap)
用户级内存映射
Linux 可以使用mmap
函数来创建新的虚拟内存,并将对象映射到这些区域中
1 |
|
例子:将任意磁盘文件赋值到stdout
1 |
|