目录
一、简述Linux系统态与用户态
内核态与用户态是操作系统的两种运行级别。
1、内核态
内核态拥有最高权限,可以访问所有系统指令;
2、用户态
用户态只能访问一部分指令;
3、什么时候会进入内核态
一共三种方式:
(1)系统调用,主动;
(2)异常,被动;
(3)设备中断,被动。
4、为什么要区分内核态和用户态呢
在CPU的所有指令中,有一些指令是非常危险的,如果错用,将导致整个系统崩溃。例如清内存、设置时钟等。所以区分内核态与用户态主要是出于安全的考虑。
二、简述LRU算法及其实现方式
1、LRU算法
LRU算法用于缓存淘汰。思路是将缓存中最近最少使用的对象进行删除。
2、实现方式
利用链表和hashmap
当需要插入新的数据项的时候,如果新数据项在链表中存在(命中),则把该节点移到链表头部,如果不存在,则新建一个节点,放到链表头部,若缓存满了,则把链表最后一个节点删除即可。
在访问数据的时候,如果数据项在链表中存在,则把该节点移到链表头部,否则返回-1,这样的话在链表尾部的节点就是最近最久未访问的数据项。
三、虚拟内存到物理地址是怎么映射的
1、什么是页表,为什么要有
页表是虚拟内存的概念。操作系统虚拟内存到物理内存的映射表,就称为页表。
原因:不可能每个虚拟内存的字节都对应到物理内存的地址,这张表将大的连物理内存的地址也放不下,于是操作系统引入页的概念。进行分页,这样可以减少虚拟内存页对应物理内存页的映射表的大小。
2、什么是操作系统的缺页中断
(1)缺页异常:malloc和mmap函数在分配内存时只是建立了进程虚拟地址空间,并没有分配虚拟内存对应的物理内存。当进程访问这些没有建立映射关系的虚拟内存时,处理器自动触发一个缺页异常,引发缺页中断。
(2)缺页中断:缺页异常后将产生一个缺页中断,此时操作系统会根据页表中的外存地址在外存中找到缺的那一页,将其调入内存。
3、虚拟地址到物理地址的映射
操作系统为每一个进程维护了一个从虚拟地址到物理地址的映射关系的数据结构,叫页表,页表中记录了这个页的基地址。
三级页表转换方法:(两步)
1、逻辑地址转线性地址:段起始地址+段内偏移地址=线性地址
2、线性地址转物理地址:
(1)每一个32位的线性地址被划分三部分:页目录索引(DIRECTION,10位)、页表索引(TABLE,10位)、页内偏移(OFFSET,12位)。
(2)从cr3中取出进程的页目录地址(操作系统调用进程时,这个地址被装入寄存器中)
页目录地址 + 页目录索引 = 页表地址
页表地址 + 页表索引 = 页地址
页地址 + 页内偏移 = 物理地址
四、简述操作系统中malloc的实现原理
malloc底层原理:当开辟的空间小于128k时,调用brk()函数;当开辟的空间大于128K时,调用mmap()。malloc采用的是内存池的管理方式,以减少内存碎片。先申请大块内存作为堆区,然后将堆区分为多个内存块。当用户申请内存时,直接从堆区分配一块合适的空闲块。采用隐式链表将所有空闲块,每个空闲块记录一个未分配、连续的内存地址。
五、一个线程占多大内存
一个Linux的线程大概占8M内存。
六、堆栈溢出
1、堆溢出:不断new一个对象,一直创建新对象,而不进行释放,最终导致内存不足,将会报错:OutOfMemory Error
2、栈溢出:一次函数调用中,栈中将被依次压入:参数、返回地址等。而函数中如果递归比较深或进入死循环,就会导致栈溢出。将会报错:StackOverflow Erro