持续创作,加速成长!这是我参与「掘金日新计划 · 10 月更文挑战」的第1天,点击查看活动详情
2.18 虚拟地址到物理地址怎么映射的?
参考回答
操作系统为每一个进程维护了一个从虚拟地址到物理地址的映射关系的数据结构,叫页表。 页表中的每一项都记录了这个页的基地址。
三级页表转换方法:(两步)
-
逻辑地址转线性地址:段起始地址+段内偏移地址=线性地址
-
线性地址转物理地址:
(1)每一个32位的线性地址被划分为三部分:页目录索引(DIRECTORY,10位)、页表索引(TABLE,10位)、页内偏移(OFFSET,12位)
(2)从cr3中取出进程的页目录地址(操作系统调用进程时,这个地址被装入寄存器中)页目录地址 + 页目录索引 = 页表地址 页表地址 + 页表索引 = 页地址 页地址 + 页内偏移 = 物理地址
按照以上两步法,就完成了一个三级页表从虚拟地址到物理地址的转换。
2.19 说说堆栈溢出是什么,会怎么样?
参考回答
堆栈溢出就是不顾堆栈中分配的局部数据块大小,向该数据块写入了过多的数据,导致数据越界。常指调用堆栈溢出,本质上一种数据结构的满溢情况。堆栈溢出可以理解为两个方面:堆溢出和栈溢出。
- 堆溢出:比如不断的new 一个对象,一直创建新的对象,而不进行释放,最终导致内存不足。将会报错:OutOfMemory Error。
- 栈溢出:一次函数调用中,栈中将被依次压入:参数,返回地址等,而方法如果递归比较深或进去死循环,就会导致栈溢出。将会报错:StackOverflow Error。
2.20 简述操作系统中malloc的实现原理
参考回答
malloc底层实现: 当开辟的空间小于 128K 时,调用 brk()函数;当开辟的空间大于 128K 时,调用mmap()。malloc采用的是内存池的管理方式,以减少内存碎片。先申请大块内存作为堆区,然后将堆区分为多个内存块。当用户申请内存时,直接从堆区分配一块合适的空闲快。采用隐式链表将所有空闲块,每一个空闲块记录了一个未分配的、连续的内存地址。
2.21 说说进程空间从高位到低位都有些什么?
参考回答
如上图,从高地址到低地址,一个程序由命令行参数和环境变量、栈、文件映射区、堆、BSS段、数据段、代码段组成。
- 命令行参数和环境变量
- 栈区: 存储局部变量、函数参数值。栈从高地址向低地址增长。是一块连续的空间。
- 文件映射区,位于堆和栈之间。
- 堆区: 动态申请内存用。堆从低地址向高地址增长。
- BSS 段:存放程序中未初始化的全局变量和静态变量的一块内存区域。
- 数据段:存放程序中已初始化的全局变量和静态变量的一块内存区域。
- 代码段: 存放程序执行代码的一块内存区域。只读,代码段的头部还会包含一些只读的常数变量。