目录

操作系统-内存内存管理

操作系统 —— (内存)内存管理

文章目录

内存管理

内存管理的目的主要有两个:一是方便用户使用;二是提高存储器的利用率。

内存管理主要有四个方面的功能:

  1. 内存空间的分配与回收:由操作系统完成主存储器空间的分配和管理,使程序员摆脱存储分配的麻烦,提高编程效率。
  2. 地址转换:在多道程序环境下,程序中的逻辑地址与内存中的物理地址不可能一致,因此存储管理必须提供地址变换功能,把逻辑地址转换成相应的物理地址
  3. 存储保护和存储共享:保证各道作业在各自的存储空间内运行,互不干扰;同时充分利用内存空间,共享内存中存放的信息。
  4. 内存空间的扩充:利用虚拟存储技术从逻辑上扩充内存。

内存管理技术

简单存储管理

可变式分区在进程装入内存时,根据进程的大小动态地建立分区,并使分区的大小正好适合进程的需要。

动态分区在开始分配时是很好的,但是之后会导致内存中出现许多小的内存块。随着时间的推移,内存中会产生越来越多的碎片,且随着进程的换入/换出,很可能会出现更多更小的内存块,内存的利用率随之下降。这些小的内存块称为外部碎片,指在所有分区外的存储空间会变成越来越多的碎片,这与固定分区中的内部碎片正好相对。

几种算法:

分配内存时顺序查找,找到大小能满足要求的第一个空闲分区。

又称最大适应(Largest Fit)算法,空闲分区以容量递减的次序链接。找到第一个能满足要求的空闲分区,也就是挑选出最大的分区。

空闲分区以容量递减的次序链接。找到第一个能满足要求的空闲分区,也就是挑选出最大的分区。

https://i-blog.csdnimg.cn/blog_migrate/5a1d2f89f21d1bc929062dc24480ada4.png

段式存储管理

  • 产生原因:如果我们将整个程序地址空间都直接放入物理内存,程序分为代码,栈,堆。他们之间不是连续的。那么 栈和堆之间空间没有被使用却占用了内存 ,这样造成了内存极大的浪费。

    所以使用分段机制,将进程地址空间里是分三个段:代码,栈,堆。 把这三个段分别独立放到物理内存中的不同位置 ,去掉中间空隙。这样更高效的利用物理内存。

    段作为独立的逻辑单位可以被其他程序段调用,这样就形成了段间连接,产生规模较大的程序。这样的特性使得段易于编译、管理、修改和保护,也便于多道程序共享。

  • 实现:每个段都有一个唯一的内部段号。段式管理通过段表对应逻辑地址和物理地址

  • 问题: 产生页外碎片 。分段会将物理内存空间分成不同长度的段,空间本身会碎片化,这对于操作系统再次给其他进程分配内存造成了麻烦。 不同的段和段之间内存中的空隙比较小的话,就不能插入一个段 ,这样会有很多的段之前都产生碎片,这就是页外碎片。

页式存储管理

而如果我们把 内存分成固定长度的单元页,并且程序也切成相同大小的页 ,这样无缝隙的插入,解决外碎片问题,这个固定长度单元 我们称之为分页。 把程序分成一页一页的,然后装入内存中的页。比如 物理内存中分页4k ,然 后把程序页内存大小也分为4K 。并且计算机处理起来更加快速,也解决了页外碎片问题。

页式存储管理方式会更加的受到欢迎,Linux 操作系统采用的就是页式存储管理方式。

缺点:1. 一段连续逻辑分布在多个页中 ,则大大降低执行效率. 2. 容易产生页内碎片 ,有的页比较大, 程序内存不满一个页,那么这个页内就会空出很多空间

功能2:虚拟页空间

交换空间:

就是用到哪一块程序的页,我们就把该页放入内存中。

所以现在内存管理,是把程序大卸八块,用到哪块装哪块进内存。

在过程中如果当前内存满了,那么我们把最不常用的内存块放到交换分区swap(硬盘),如果要使用该块,则再拿回来,把这个再装入内存。这个就是页面置换算法(涉及到缓存的基本都是这个算法)。

页式存储管理方式使得加载程序的时候,不再需要一次性都把程序加载到内存中,而是在程序运行中需要用到的对应虚拟内存页里面的指令和数据时,再将其加载到内存中,这些操作由操作系统来完成。当 CPU 要读取特定的页,但却发现页的内容却没有加载时,就会触发一个来自 CPU 的缺页错误(Page Fault)。此时操作系统会捕获这个错误,然后找到对应的页并加载到内存中。通过这种方式,使得我们可以运行哪些远大于实例物理内存的程序,但相对的执行效率也会有所下降。

  • 内存页交换策略

    产生场景:程序要使用的页不存在于物理内存中, 会产生缺页中断 ,从硬盘中取得缺的页放入内存, 如果物理内存已满 ,还会根据某种算将磁盘中页进行交换。

  1. FIFO:先进先出,谁先进来谁就先出去。但是可能剔除重要的页。

  2. LRU:最近使用原则:每个最近被访问的都会被提到队头,然后删除最久未访问的。1)新数据插入到链表头部;2)每当缓存命中(即缓存数据被访问),则将数据移到链表头部;3)当链表满的时候,将链表尾部的数据丢弃。

  3. LFU:最不常用算法:每个访问页计数,置换访问次数最少的页面,将计数最小的替换。

  4. 时钟置换算法(Clock):是FIFO和LRU的结合。 环形链表 ,不再排序而是使用2个标记, 0和1 ,第一个次加载到该页的时候,页标记被设置为0,内存中再次访问该页则标记该页面为1。当需要替换时,指针从当前位置循环查找环形链表(类似于FIFO), 如果遇到标记为1的,标记为0,不替换如果遇到标记为0的,替换它

    https://i-blog.csdnimg.cn/blog_migrate/277f061bedb2e08c0fa2eb2925c26171.png

实现:页表

为了记录地址空间的每个虚拟页放在物理内存中的位置,操作系统通常为每个进程保 存一个数据结构,称为页表

页表的主要作用是为地址空间的每个虚拟页面保 存地址转换

第一次就是通过虚拟页表地址,然后加上偏移量,得到实际物理页表地址。

第二次就是根据第一次得到的物理地址访问内存取出数据。

多级页表:引入多级页表的主要目的是为了避免把全部页表一直放在内存中占用过多空间,特别是那些根本就不需要的页表就不需要保留在内存中。

快表TLB:提高访问速度

为了减少两次访问内存导致的效率影响,分页管理中引入了快表机制, 相当于再加一层缓存 ,是一种 访问速度比内存快很多的高速缓存 ,用来存放最近访问的页表项的副本,可以加速地址变换的速度(基本地址变换机构要访存2次)

步骤:

根据虚拟地址中的页号查快表;

如果该页在快表中,直接从快表中读取相应的物理地址;

如果该页不在快表中,就访问内存中的页表,再从页表中得到物理地址,同时将页表中的该映射表项添加到快表中;

当快表填满后,又要登记新页时,就按照一定的淘汰策略淘汰掉快表中的一个页。

分页和分段有什么区别(内存管理)?

和我们平时经常在我们开发的系统使用的缓存很像

段式存储管理是一种符合用户视角的内存分配管理方案。在段式存储管理中,将程序的地址空间划分为若干段(segment),如代码段,数据段,堆栈段;这样每个进程有一个二维地址空间,相互独立,互不干扰。段式管理的优点是:没有内碎片(因为段大小可变,改变段大小来消除内碎片)。但段换入换出时,会产生外碎片(比如4k的段换5k的段,会产生1k的外碎片)

页式存储管理方案是一种用户视角内存与物理内存相分离的内存分配管理方案。在页式存储管理中,将程序的逻辑地址划分为固定大小的页(page),而物理内存划分为同样大小的帧,程序加载时,可以将任意一页放入内存中任意一个帧,这些帧不必连续,从而实现了离散分离。页式存储管理的优点是:没有外碎片(因为页的大小固定),但会产生内碎片(一个页可能填充不满)。

两者的不同点:

目的不同:分页是由于系统管理的需要而不是用户的需要,它是信息的物理单位;分段的目的是为了能更好地满足用户的需要,它是信息的逻辑单位,它含有一组其意义相对完整的信息;

大小不同:页的大小固定且由系统决定,而段的长度却不固定,由其所完成的功能决定;

地址空间不同: 段向用户提供二维地址空间;页向用户提供的是一维地址空间;

信息共享:段是信息的逻辑单位,便于存储保护和信息的共享,页的保护和共享受到限制;

内存碎片:页式存储管理的优点是没有外碎片(因为页的大小固定),但会产生内碎片(一个页可能填充不满);而段式管理的优点是没有内碎片(因为段大小可变,改变段大小来消除内碎片)。但段换入换出时,会产生外碎片(比如4k的段换5k的段,会产生1k的外碎片)。

段页式存储管理:

  1. 先把程序的内存按段分成若干段,满足程序需求, 因为程序按段来划分执行效率更高
  2. 再把段按照页式管理分成若干页,并将页存放到物理内存中。 提高计算机内存效率

段页式管理结合了段式管理和页式管理的优点。简单来说,段页式管理机制就是把主存先分成若干页,每个页又分成若干段。如此的,段页式管理机制中段与段之间以及段的内部的都是离散的。显然,段页式管理是一种折中的方式,具有广泛的通用性。

这样既满足了用户需求,又满足计算机需求,减少内存碎片。

页是物理单位,从物理角度

段是逻辑单位,主要时满足用户需求,段的划分是不固定的。

缺点:实现复杂,效率更低,维护成本更高。