1.逻辑地址和物理地址?进程的地址空间。内存,虚拟内存和交换空间是怎么回事? 为什么进程地址空间可以比物理内存大?
个人理解这个这个问题就通俗的比喻下就是一座高楼,和图纸的比喻。(虽然这个在后面分页分段的映射上不能使用,但是这是一个区别物理和逻辑地址好的方法)。
物理地址就是楼层的建好后的实体, 每个物理地址代表这个楼房的一个位置。
逻辑地址就好比手里拿到的工程师拿到图纸,你也可以通过地址指出楼的不同位置,但是只是逻辑上的,而不是实际运行的。
进程的地址空间其实也类比下,实际的物理地址空间。比如32位的物理地址空间为0~4G这个范围内的空间。 逻辑地址当然也是纸面上的地址空间。每个进程有它们自己的图纸,也就有它们自己的地址空间。
内存就是物理内存,虚拟内存其实是一种技术。虚拟内存技术,使得在进程执行过程中,通过页面置换来实现多道程序并发运行的。很多书上讲到的虚拟内存,其实更贴切的应该成为逻辑内存。就是图纸上的需要的内存。
linux上top命令显示的 VIRT结果其实就是进程“需要的”虚拟内存大小,包括进程使用的库、代码、数据,以及malloc、new分配的堆空间和分配的栈空间等。
具体区别参考:linux top 命令---VIRT,RES,SHR,虚拟内存和物理内存
交换空间指的是在磁盘上开辟的一个分区,这个分区用来在进程切换的过程中,当需要的指令不在物理内存,而物理内存都被占用时进行换进换出操作的。
最后一个问题,虚拟内存其实就是图纸。图纸可以画出超出楼层,比如来个地下室,但是物理内存是固定的,他不能说加就加。
内存机制是用怎样的方法保证各个进程之间执行时不会影响?
每个进程都有自己的图纸,也就是有自己的地址空间,每次在被调到内存的时候,
1.早期的时候,它是有一个基地址寄存器和界限地址寄存器,他每次在被加载到内存的时候,都会保存好这两个寄存器,然后每次 访问的时候都会根据这两个寄存器的值来进行保护。后来有了分段和分页技术,他们都有类似与前面的寄存器的东西,存放在段表和页表中,每次访问的时候,都是通过这两个东西保证不会访问其他进程的内存。他们的值是不可以随便改的,只有操作系统有权限改。
内存分配分段和分页机制?
分段:在进程编译,链接,生产逻辑地址的时候,就把他们分别进行分段,分为代码段,数据段,堆栈,堆等等。然后在执行的时候把每一段的内容分别映射到物理内存上,并通过段表来进行记录,所以每个进程应该都有一个段表。其中包括每一段的基地址和界限地址。
分页:将每个进程执行前,把逻辑地址空间进行分页,分成很多很多小的页面,同时把物理内存也根据页面的大小分为很多很多页框(帧 )(再次强调注意在书中用词,逻辑地址空间的分出来的部分叫页面,物理内存中分出来的叫帧)。当进程中的页面加载到内存中后,通过页表进行记录。
4.虚拟内存怎么理解?
答案参见1中
5.什么是写时复制?
这个主要用于在父进程创建子进程的时候,而子进程一般会直接exec()替换新的地址空间,所以没有必要在fork的时候进行复制父进程的地址空间,而是让父子共享父进程的地址空间。但是也有那种不进行exec的子进程,那么这种只有父子进程开始修改共享部分的时候,共享部分才会复制一个副本,达到父子进程互不影响的目的。
一般的只有写的时候,才进行复制,而写是只有写的那一页进行复制,没写到的页面不会复制,这个是在页表中的一个单独的保护位来实现的。
为了取消写时拷贝,父子同步共享一个数据时,一般可以使用vfork()代替。但vfork()主要还是用于 创建后直接exec()。
- 页面置换算法?
一般页面置换算法有:FIFO 算法,OPT(最优页面置换)算法,LRU(最近最少使用),基于计数的页面置换和 页面缓冲池算法
主要说下OPT 和LRU的区别:
注意看两个概念: OPT的算法是最长时间不会使用,而LRU是最长时间没有使用。细细的思考,就会发现一个是未来时间,一个是过去时间。
如果还没看懂,就来看看两个图的比较。
看出来区别了吗?OPT算法的在第五次置换的时候把刚执行过的0页面换出去了。这个它虽然名字是最优置换,但是不一定就是最优的解法了。
7.共享内存的实现?
其实共享内存主要用了两种技术手段。
一种是内存映射技术,一种是绑定地址。
共享内存首先是在自己的地址空间建立一个共享内存区域。然后通过映射的方法,绑定到物理内存。这个区域比其他的区域不同,它可以被其他的进程 通过映射的方式绑定,也就是说,多个进程的逻辑内存,可以绑定同一个物理内存地址。从而实现了进程间的数据共享。
- 内存分配策略?
主要两种策略,一种是伙伴系统,一种是slab分配器。
伙伴系统是:每次把一块内存一分为2, 他们都是2的幂次方大小的内存块。两个相同的内存块互为伙伴。然后通过一个结构体数组进行连接,每个结构体后面都对应的一个链表,它们分别会把不同大小的内存块进行连接,从而以后每次需要内存块的时候,可以快速的查找到匹配的内存块。(但是伙伴系统会产生内部碎片)。
slab分配:
它类似于一个包含了一系列的不同结构体的内存池。
在内核中,对于一些常用的数据结构PCB,文件描述符等,因为经常使用到,所以每次创建和释放都是很麻烦的,所以内核为它们准备了以后分好的内存,每次使用直接使用这个结构体,用完了以后再还给slab,这样就加快内存分配的效率,并且将内核中经常使用的这些对象池放到高速缓存中。
一般对于这种动态存储进行匹配的时候,可以使用首次适应,最优适应等适配方法。