为什么要有虚拟内存?
github: https://github.com/AriseFX/java-notes
有且仅有这一种办法:将一个程序加载到内存,PC指向程序首地址, 在CPU取指执行的过程中,内存已经被使用了。 程序是存储在磁盘上的(先忽略加载的过程), 那么程序该加载到内存的哪个位置呢?
如果40和0都是真实的物理地址,为了让『call 40』好使,main必须放到物理内存中40位置,局限性相当大,要是其他程序也想放到40位置呢,那么先得需要找到空闲内存。
如果恰好1000位置空闲,那么把程序加载到1000位置,并1000赋给IP,CPU开始取值执行, 『call 40』又跳到了物理内存40位置,还是不好使。 仅仅修改PC初始地址是不够的, 还需要另外一个概念:重定位(修改程序中的地址)
编译连接时/加载时?
swap
运行时重定位
那么整理一下思路,程序载入是整个一起载入内存的吗?
页表该如何设计?
既要连续又要降低空间复杂度,那么就有了多级页表。
多级页表引入了新的问题
如何使用内存,前面提到过:先把程序『放入内存』,在CPU取指执行的过程中就开始『使用内存』了。
那么linux何时开始进行内存管理呢? 很容易想到从fork系统调用的内存分配阶段开始:分配段、建段表;
分配页、建页表。
总结:
经过一顿折腾,终于可以看『换入』是咋实现的了!
内存是有限的,不可能总是获取到新的页,那么物理内存不够的时候需要把一部分页面换出。关于页面换出涉及好几个页面置换算法,
由于篇幅问题这里只详细介绍最有效的(较少的缺页次数)。
LRU实现:
下面介绍实际操作系统的LRU近似实现:
1. https://pdos.csail.mit.edu/6.828/2018/xv6/book-rev11.pdf
2. <<x86汇编语言:从实模式到保护模式>>
3. <<深入理解计算机系统>>
2024-06-18 广告