内存管理的发展
-
原始内存管理
- 内核和进程都运行在物理内存上,内核与进程之间没有做隔离,进程可以随意干扰、窃取内核的数据。而且进程和内核没有权限的区分,进程可以随意做一些敏感操作。
-
分段内存管理
- 分段内存管理需要硬件的支持和软件的配合。软件把物理内存分成一个一个段,每个段都有段基址、段限长、段类型和段权限。段类型分为代码段和数据段。段权限分为特权段和用户段。(这就完美解决原始内存管理存在的问题)
- 但是当时物理内存小,能同时运行的进程比较少,运行进程的吞吐量比较少。所以通过在程序上实现多个功能模块,在程序运行时他们会占用同一段物理内存地址,再在代码里写好内存覆盖,从而实现多个模块占用较少的物理内存,也能运行下去。
-
分页内存管理(虚拟内存管理)
- 也是需要硬件的支持和软件的配合。
- 虚拟内存空间又分为两部分,内核空间和用户空间,内核空间只有一个,用户空间有N个,所有的虚拟内存空间都共享同一个内核空间,每个进程有自己的用户空间。
- 页表是由内核负责创建和维护的。一套页表可以用来表达一个虚拟内存空间,不同的进程可以用不同的页表集,页表集是可以不停地切换的,哪个进程正在运行就切换到哪个进程的页表集。
- CPU都是通过MMU访问虚拟内存地址的,MMU(Memory Management Unit,该硬件是集成在CPU内部的)会用页表去解析虚拟内存,如果找到了其对应的物理地址就直接访问,如果页表项是空的,就会触发缺页异常,在缺页异常中会去分配物理内存并建立页表映射。然后再重新执行刚才的那条指令,然后CPU还是通过MMU访问内存,由于页表建立好了,这下就可以访问到物理内存了。
物理内存回收
内存回收首先考虑的是内存规整,也就是内存碎片整理,因为有可能我们不是可用内存不足了,而是内存太分散了,没法分配连续的内存。内存规整之后如果还是分配不到内存的话,就会进行页帧回收。
如果页帧回收之后还没有得到足够的物理内存,内核将会使用最后一招,OOM Killer。OOM Killer会按照一定的规则选择一个进程将其杀死,然后其物理内存就被释放了。
把进程占用的但是当前并不在使用的物理内存进行回收,并分配给新的进程来使用的过程就叫做换页。
页帧回收
-
内核空间
- 内核空间的物理内存是不换页的,所以内核只会进行缓存回收。
- 内核会使用内存作为文件缓存(page cache),从而提高文件性能。当内存紧张时,文件缓存页面中脏页回写到存储设备中,干净的页面丢弃,从而释放内存。
- 内核还有内存压缩技术,后面再了解下。
-
用户空间
- 用户空间的物理内存是可以换页的,所以会对用户空间的物理内存进行换页以便回收其物理内存。
- 用户空间的物理内存分为文件页和匿名页。
- 对于文件页(内容来源于文件,如程序的代码区、数据区),如果其是clean的,可以直接丢弃内容,回收其物理内存,如果其是dirty的,则会先把其内容写回到文件,然后再回收内存。
- 对于匿名页(没有内容来源,由内核直接为其分配内存,如进程的堆和栈),如果系统配置的有swap区的话,则会把其内容先写入swap区,然后再回收,如果系统没有swap区的话则不会进行回收。
- 进程被换页的物理内存后面如果再被使用到的话,还会通过缺页异常重新把文件加载到内存,分配物理内存地址。