操作系统篇-内存管理

以下主要讲述进程到内存的映射

1.内存管理发展历程

1.1单进程DOS时代

DOS时代 - 同一时间只能有一个进程在运行,单进程
windows9x开始,多个进程可以装入内存
引发问题:
内存撑爆
互相打扰
在这里插入图片描述

1.2 内存管理

为了解决上面说的问题,引入现在的内存管理系统:使用虚拟地址、分页装入、软硬件结合寻址。

1.2.1 解决内存撑爆

将内存分页(内存不够用),内存中分成固定大小的页框(4K),把程序(硬盘上)分成4K大小的块,用到哪一块,加载那一块,加载的过程中,如果内存已经满了,会把最不常用的一块放到swap分区, 把最新的一块加载进来(LRU算法)

例如,执行QQ.exe时,把它的分好页的页表记录下来,执行时,用到页表中的哪一页,就将这页加载进内存中。
在加载的过程中,如果内存已经满了,会把最不常用的一块放到swap分区(linux交换分区), 把最新的一块加载进来(LRU算法)。
在这里插入图片描述
几乎所有涉及到缓存的,都用到了LRU(Least Recently Used:最不常用)或LFU算法。

如何设计LFU缓存机制,支持获取数据,写入数据O(1)复杂度:
如果是数组,每个元素保存时间戳,如果查一遍,复杂度是O(n)
如果用单链表,最近用的加到尾部,头部肯定是最不常用。当中某一个又用到时,是需要挪动位置的,这些是指针操作O(1),但是查找某一个元素还是O(n)
改进:用hashmap哈希表(保证 查找操作O(1))+ 双向链表 (链表保证 排序操作和新增操作 O(1),双向链表保证找到的元素块的左边指针指向的块可以指向右边块),java的LinkedHashMap就是这样实现缓存
在这里插入图片描述

1.2.2 解决相互打扰的问题

虚拟内存
为了保证互不影响 - 让进程工作在虚拟空间,程序中用到的空间地址不再是直接的物理地址,而是虚拟的地址,这样,A进程永远不可能访问到B进程的空间。
虚拟空间大小:看寻址空间 - 64位系统 2 ^ 64,32位系统2^32 (表达有2^32个不同的内存地址),而每个地址可以存放8bit的数据,即单位是byte
站在虚拟空间的角度,进程是独享整个系统 + CPU

虚拟空间分段,段内分页,需要哪页加载到页框
在这里插入图片描述
程序用的虚拟地址,那怎么和物理地址映射:
偏移量(如下20) + 段的基地址(如下1000) = 线性地址 (虚拟空间)
得到线性地址后,通过 OS + MMU(cpu内部硬件 Memory Management Unit)
在这里插入图片描述
通过下图再深入了解
P1,P2,P3,P4 4个进程都认为自己是独占整个内核的,实际上是共享操作系统内核。
MMU给每一个进程分配他们的内存资源。
如果内存装满了,使用LRU算法将最不常使用的页放入硬盘的交换空间中。
在这里插入图片描述
缺页中断
在执行一条指令时,如果发现需要用到页在内存中没有,那么停止该指令的执行,并产生一个缺页异常(中断),由内核处理并加载,之后,原先引起的异常的指令就可以继续执行,而不再产生异常。

猜你喜欢

转载自blog.csdn.net/qq_33873431/article/details/112003010
今日推荐