linux 的虚拟内存管理有几个关键概念:
1.每个进程都有独立的虚拟地址空间,进程访问的虚拟地址并不是真正的物理地址;
2.虚拟地址可通过每个进程上的页表(在每个进程的内核虚拟地址空间)与物理地址进行映射,获得真正物理地址;
3.如果虚拟地址对应物理地址不在物理内存中,则产生缺页中断,真正分配物理地址,同时更新进程的页表;如果此时物理内存已耗尽,则根据内存替换算法淘汰部分页面至物理磁盘中。
内存分配的原理
从操作系统角度来看,进程分配内存有两种方式,分别由两个系统调用完成:brk和mmap(不考虑共享内存)。
1.brk是将数据段(.data)的最高地址指针_edata往高地址推;
维护一个位置。brk/sbrk改变这个位置
brk改变绝对位置。
sbrk相对改变位置。
2.mmap是在进程的虚拟地址空间中(堆和栈中间,称为文件映射区域的地方)找一块空闲的虚拟内存。
void *mmap(
void *start,//指定映射的虚拟地址 0由系统指定开始位置)
size_t length,//映射空间大小 pagesize倍数
int prot,//映射权限 PROT_NONE | PROT_READ PROT_WRITE PROT_EXEC
int flags,//映射方式MAP_ANONYMOUS MAP_SHARED和MAP_PRIVATE二选一 等
int fd,//文件描述符号
offset_t off);//文件中的映射开始位置(必须是pagesize的倍数)
映射方式:
1.内存映射:匿名映射。
2.文件映射:映射到某个文件,只有文件映射最后两个参数有效。
小结
这两种方式分配的都是虚拟内存,没有分配物理内存。在第一次访问已分配的虚拟地址空间的时候,发生缺页中断,操作系统负责分配物理内存,然后建立虚拟内存和物理内存之间的映射关系。
在标准C库中,提供了malloc/free函数分配释放内存,这两个函数底层是由brk,mmap,munmap这些系统调用实现的。
参考:https://blog.csdn.net/weixin_36145588/article/details/78363836