内存分配——分页&&分段

    技术2022-07-11  125

    关于计算机内存分配,主要有两种:连续内存分配和非联系内存分配。需要注意的是,这是操作系统级别的,而堆与栈的内存分配,是属于编译器级别的,具体可以参考另一篇笔记:

    https://blog.csdn.net/weixin_48206549/article/details/107028392

    一.连续内存分配

    连续内存分配是指为一个程序分配地址连续的一段内存,当出现许多程序时,由于程序大小不一必然会出现许多的内存碎片,无法充分发挥出所有内存的价值,一般来说,连续内存分配主要有三种形式: ①首次适配: 遍历内存,在第一个能够将程序放进去的地方进行内存分配 ②最佳适配: 需要统计所有可用内存,按大小排序,选择满足程序所需的最小的内存,容易产生很多细小的碎片 ③最差适配: 同样需要统计可用内存并排序,每次都给程序分配最大的内存,不断将大的内存拆分,这样小的碎片少了,但是较大的内存很快就分配完了,无法支持较大的程序。 显然,这三种并不好评判优劣,反正都不咋地…

    二.非连续内存分配

    1. 分段

    按一定规则对程序进行拆分,如将程序拆分成数据段、txt段、堆、运行栈等,并分别映射到内存的不同位置,实现程序的分段。显然这些段的大小不是固定的,由程序员编写程序控制。 段寻址方式 CPU根据段号+段内偏移通过内存管理单元MMU中的段表进行地址映射,直接找到程序的物理地址,而段表的建立则是由操作系统来完成的。

    2.分页(常用)

    页寻址方式 CPU寻址时同样需要页号和页偏移,和分段寻址的不同主要有两点 ①页表的大小是固定的 ②利用了一个新的抽象——帧的概念

    关于页和帧做一点补充: 物理内存划分成固定大小的帧(2的幂次) 逻辑内存划分成固定大小的页,其中页的大小与帧的大小保持一致 利用页帧的帧号和偏移可以唯一确定一个物理地址,这是写在硬件的

    寻址过程:CPU根据页号在页表中找到对应的帧号,页内偏移同时也代表了帧内偏移,因此可以找到所要访问的数据或指令的物理地址

    页寻址还存在两个问题: ①时间上:CPU每次寻址需要访问内存两次,第一次访问页表,第二次访问物理内存,比较耗时 ②空间上:每个程序都有对应的页表,在内存中存放大量页表占用空间。 为了解决以上问题,提出了两个新的概念:TLB和多级页表

    TLB快表(Translation Look-aside Buffer) 快表存放在CPU内部的MMU中,访问起来速度很快,把常用的页表小加入TLB缓存可以有效提高CPU寻址效率。 TLB使用key-value关联内存实现,具备快速访问的性能 如果TLB命中将快速访问到物理内存;如果没有命中,就去查询页表,并且将对应的表项加载到TLB缓存中来。

    多级页表 以二级页表为例 将页号拆分成两部分,访问一级页表时看前半部分进行查询,找到对应的表项,此时页表中存放的内容不再是页帧号,而是对应的二级页表的起始地址,再去访问二级页表得到页帧号,最终访问到物理内存。分级页表可以及时将不存在的页表项从内存中删除,达到节省空间的效果。(如果放到一个页表中,对于其中几个页表项无法进行删除,因为页表大小固定了,就算抹去对应的内容空间占用也无法避免,但是多级页表将一个页表拆分,那么对于那些失效的页表项,此时单独分离出来形成子表,那么就可以直接删除子表达到节约内存的效果)

    Processed: 0.015, SQL: 9