2024年Go最全操作系统—内存管理_多级页表的底层(1),Golang程序员

img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Go语言开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以戳这里获取

虚拟内存是计算机系统内存管理的一种技术。它使得应用程序能够访问比物理内存更大的地址空间。虚拟内存的主要目的和优点如下:

  1. 内存抽象:虚拟内存将物理内存抽象成连续的地址空间,使得每个应用程序都有自己独立的地址空间。这样,程序员不需要关心物理内存布局,也不需要考虑内存碎片问题。
  2. 内存隔离:虚拟内存为每个进程提供了独立的地址空间,确保一个进程的内存访问不会影响到其他进程的内存。这提高了系统的稳定性和安全性。
  3. 内存管理灵活性:虚拟内存允许操作系统更灵活地管理内存资源。例如,操作系统可以将不常用的内存页面移出到磁盘上的交换空间(swap space),从而为其他更需要内存的进程腾出空间。这种技术称为“页面置换”或“交换”。
  4. 内存利用率提高:虚拟内存允许多个进程共享系统的物理内存。通过按需分配内存(即仅在进程需要时分配内存),虚拟内存提高了内存的利用率。
  5. 程序加载优化:虚拟内存允许操作系统按需加载程序的部分内容到内存中。例如,一个大型程序可能只需要加载一部分常用的代码和数据到内存,而不需要一次性加载整个程序。这使得程序启动更快,同时节省了内存资源。

总之,虚拟内存技术为计算机系统提供了更高效、安全和灵活的内存管理方式。它使程序开发者能够以更简单的方式编写代码,同时还提高了整个系统的性能和稳定性。

虚拟内存的实现方式

虚拟内存的实现依赖于硬件和操作系统的协同工作。以下是虚拟内存的主要实现方式:

1.分页

在操作系统中,分页(Paging)是一种内存管理技术,用于将虚拟内存空间分割成大小固定的块,称为“页”(Page)。同样地,物理内存也被划分为大小相同的块,称为“页框”(Page Frame)或“帧”(Frame)。操作系统通过页表(Page Table)来管理虚拟地址与物理地址之间的映射关系。

分页技术的主要目的是实现虚拟内存的概念,使得程序员不需要关心物理内存的实际分布和限制。程序可以在一个连续的虚拟地址空间中运行,而操作系统会负责将这些虚拟地址映射到物理内存中的实际地址。这种映射使得不同程序之间的内存空间隔离,避免了程序间的内存访问冲突。

分页技术具有以下优点:

  1. 内存利用率提高:通过分页,操作系统可以将物理内存中的碎片化空间合并使用,提高内存利用率。
  2. 内存保护:每个程序都在独立的虚拟地址空间中运行,避免了程序间的内存访问冲突,提高了系统的稳定性。
  3. 动态加载与换出:操作系统可以根据需要将程序的部分页加载到内存中或者将不再需要的页换出到磁盘上,实现内存的动态管理。

分页技术的缺点主要是性能损耗。因为每次访问内存时,都需要通过页表进行地址转换,这会导致一定的时间开销。为了减少这种开销,现代处理器通常配有高速缓存(如Translation Lookaside Buffer, TLB),用于存储最近使用过的虚拟地址与物理地址之间的映射关系,从而提高地址转换的速度。

查找过程

操作系统使用分页(paging)机制来管理内存和实现虚拟内存。在分页系统中,内存被划分为固定大小的单元,称为页(page)。同样,虚拟内存也被划分为与页大小相同的单元,称为页框(page frame)。操作系统使用一个叫做页表(page table)的数据结构来记录虚拟内存中的每个页对应的物理内存中的页框。

在分页系统中查找地址的过程如下:

  1. 计算虚拟地址:当程序访问内存时,它会生成一个虚拟地址。虚拟地址可以分为两部分:虚拟页号(virtual page number, VPN)和页内偏移(offset within the page)。
  2. 查找页表:操作系统为每个进程维护一个页表。页表中的每个条目(称为页表项,PTE)包含虚拟页号和对应的物理页框号(physical frame number, PFN)。操作系统使用虚拟页号作为索引在页表中查找对应的页表项。
  3. 检查页表项:找到页表项后,操作系统会检查该项是否有效。如果无效,说明该虚拟地址尚未映射到物理内存,操作系统需要执行缺页处理(如分配新的物理内存并更新页表项)。
  4. 计算物理地址:如果页表项有效,操作系统可以从中获取物理页框号。然后,将物理页框号和虚拟地址中的页内偏移组合起来计算出物理地址。
  5. 访问物理内存:最后,操作系统使用计算出的物理地址访问物理内存,读取或写入数据。

这个过程总结为以下步骤:

物理地址 = (PFN << page_size_bits) | offset

其中,PFN 是从页表项中获得的物理页框号,page_size_bits 是页大小的比特数(如 4KB 页大小对应 12 比特),offset 是虚拟地址中的页内偏移。

分页系统的设计使得操作系统可以在不同的物理内存位置分配虚拟内存,实现内存隔离和保护。同时,分页系统还支持实现虚拟内存的特性,如按需加载、内存共享等。

页表的底层实现

操作系统中页表的底层实现通常采用数组或者树形数据结构。具体实现取决于操作系统和硬件架构。

  1. 数组:在单级页表的实现中,通常使用数组作为底层数据结构。每个进程都有一个独立的页表,页表中的每个元素(页表项,PTE)对应一个虚拟页。操作系统通过虚拟页号(VPN)作为索引直接在数组中查找相应的物理页框号(PFN)。
  2. 树形数据结构:多级页表和部分硬件支持的页表实现(如 x86 架构的页目录和页表)通常采用树形数据结构。最常见的是二级页表,它将虚拟地址划分为两部分:一级页表索引(P1)和二级页表索引(P2)。操作系统首先使用 P1 查找一级页表,然后使用 P2 查找二级页表。最后,从二级页表中找到的页表项包含物理页框号。多级页表可以进一步扩展为三级、四级等更多级别的树形结构,以适应更大的地址空间。

这些数据结构通常与硬件紧密相关,现代处理器往往提供硬件支持的页表实现,以加速虚拟地址到物理地址的转换过程。例如,x86 架构中的页目录和页表,以及 ARM 架构中的转换表(Translation Tables)都是基于树形数据结构的硬件页表实现。

2.分段

在操作系统中,分段(Segmentation)是另一种内存管理技术,它将程序的虚拟内存空间划分为多个逻辑上独立的部分,称为“段”(Segment)。每个段都有一个独立的起始地址和长度。分段技术的主要目的是支持程序中的逻辑结构,例如代码段、数据段和栈段等,提高内存管理的灵活性。

分段技术的基本原理是将程序的逻辑地址(段号和段内偏移量)映射为物理内存中的实际地址。为了实现这种映射,操作系统使用了一种叫做段表(Segment Table)的数据结构。段表中的每个条目包含了一个段的基地址和长度,操作系统根据逻辑地址中的段号在段表中查找相应的基地址,然后将基地址和段内偏移量相加,得到物理地址。

分段技术具有以下优点:

  1. 支持程序的逻辑结构:分段允许程序员根据程序的逻辑结构(如代码、数据和栈等)来组织内存空间,提高了内存管理的灵活性。
  2. 内存保护:通过为每个段设置访问权限(如只读、可读写等),操作系统可以实现内存空间的保护,防止程序在运行过程中意外地修改了其他段的内容。
  3. 动态加载与卸载:操作系统可以根据需要动态地将程序的某个段加载到内存中,或者将不再需要的段卸载出内存,实现内存的动态管理。

然而,分段技术的主要缺点是内存碎片问题。由于段的大小不固定,当程序运行一段时间后,内存中可能会出现很多大小不一的空闲空间,导致内存利用率降低。为了克服这个问题,很多操作系统采用了分页和分段相结合的内存管理方案,充分利用了两种技术的优点。

[外链图片转存中...(img-EeHy81fy-1691238615233)]

段表的底层实现

在操作系统中,段表的底层实现通常采用数组作为数据结构。段表用于存储虚拟地址到物理地址的映射信息,以支持基于段的内存管理方式。

3.段页式

段页式虚拟内存结合了分段(Segmentation)和分页两种方法。在段页式系统中,虚拟地址空间首先被划分为多个独立的段(Segment),每个段可以有不同的大小和属性(如代码段、数据段等)。然后,每个段被进一步划分为固定大小的页。段页式虚拟内存允许程序员根据程序的逻辑结构分配内存,并提供了内存保护和共享的功能。段页式虚拟内存的实现需要硬件支持,如 x86 架构中的 Intel 80386 及以后的处理器。地址结构就由段号、段内页号和页内位移三部分组成。

段页式地址变换中要得到物理地址须经过三次内存访问:

  • 第一次访问段表,得到页表起始地址;
  • 第二次访问页表,得到物理页号;
  • 第三次将物理页号与页内位移组合,得到物理地址。

虚拟内存的实现需要硬件和操作系统的支持。例如,现代处理器通常包含内存管理单元(Memory Management Unit,MMU),用于处理虚拟地址到物理地址的转换和内存访问控制。操作系统负责管理页表、处理缺页中断、分配和回收内存等任务。

[外链图片转存中...(img-lkSbqlPG-1691238615235)]

分段和分页有什么区别

分段(Segmentation)和分页(Paging)都是内存管理技术,用于实现虚拟内存。它们之间的主要区别如下:

  1. 地址空间划分

    • 分段:将虚拟地址空间划分为多个不同大小的段(Segment),每个段具有自己的基址(Base Address)和界限(Limit)。段的大小取决于程序的逻辑结构,例如代码段、数据段和堆栈段。
    • 分页:将虚拟地址空间和物理地址空间都划分为固定大小的页(Page)。每个虚拟页可以映射到一个物理页或硬盘上的交换空间。页的大小通常是2的幂次方(如4KB、8KB等)。
  2. 内存映射方式

    • 分段:虚拟地址包含一个段选择器(Segment Selector)和一个偏移量(Offset)。物理地址是基址加上偏移量。分段的内存映射关系由段表(Segment Table)维护。
    • 分页:虚拟地址被划分为页号(Page Number)和页内偏移(Offset within Page)。物理地址由物理页号和页内偏移组成。分页的内存映射关系由页表(Page Table)维护。
  3. 内存分配和管理

    • 分段:内存分配基于段,每个段的大小可以根据需要动态调整。分段内存管理更符合程序的逻辑结构,但可能导致内存碎片问题。
    • 分页:内存分配基于页,页的大小是固定的。分页内存管理简化了内存分配和回收过程,减少了内存碎片问题,但可能导致内存浪费(部分页未被完全使用)。
  4. 内存保护和共享

    • 分段:每个段都有自己的访问权限和属性,如只读、可执行等。这有助于实现内存保护和共享。例如,多个程序可以共享一个只读的代码段。
    • 分页:虽然分页本身没有提供内存保护和共享功能,但许多分页系统通过扩展页表项来支持这些功能,例如页表项中的访问权限位和脏位(Dirty Bit)。

总之,分段和分页都是实现虚拟内存的方法,但它们在地址空间划分、内存映射方式、内存分配和管理以及内存保护和共享方面有所不同。现代操作系统通常采用分页或段页式虚拟内存(结合分段和分页的优点)。

什么是交换空间

交换空间(Swap Space)是计算机系统中用于支持虚拟内存管理的一种存储区域,通常位于硬盘或固态硬盘上。当物理内存(RAM)不足以容纳所有运行中的程序和数据时,操作系统会将一部分数据(通常是最近较少使用的页面或段)从物理内存移出到交换空间,从而为其他程序或数据腾出内存空间。这个过程被称为“交换”(Swapping)或“页面交换”(Page Swapping)。

交换空间的主要作用是扩展可用内存资源,使计算机系统能够运行更多的程序或处理更大的数据。然而,由于硬盘或固态硬盘的访问速度远低于物理内存,频繁发生交换操作会导致系统性能下降。因此,交换空间主要作为一种补充手段,而不是内存的替代品。

在不同的操作系统中,交换空间的具体实现方式可能有所不同。例如:

  • 在Linux和UNIX系统中,交换空间可以是一个专门的磁盘分区(Swap Partition)或一个交换文件(Swap File)。
  • 在Windows系统中,交换空间通常被称为“虚拟内存文件”或“页文件”(Page File),默认保存在系统分区的根目录下,文件名为 pagefile.sys。

为了提高系统性能,建议将交换空间放置在最快的硬盘上,并根据系统的内存使用情况调整交换空间的大小。在具有足够物理内存的现代计算机系统中,可以适当减少对交换空间的依赖以提高性能。

物理地址、逻辑地址、有效地址、线性地址、虚拟地址

这些地址类型都与内存管理和访问相关,它们之间的区别如下:

  1. 物理地址(Physical Address):物理地址是计算机硬件(如CPU和内存)用于访问内存的实际地址。它直接对应于物理内存(RAM)上的一个位置。在物理内存中,每个字节都有一个唯一的物理地址。
  2. 逻辑地址(Logical Address):逻辑地址是程序在编译时分配的地址,它表示程序内存访问的相对位置。逻辑地址与程序的逻辑结构相关,如代码段、数据段和堆栈段。在程序加载到内存并运行时,逻辑地址会被转换为实际的物理地址或虚拟地址。
  3. 有效地址(Effective Address):有效地址是CPU在执行指令时用于计算实际内存访问地址的中间结果。对于某些体系结构,有效地址可能需要与基址(Base Address)或段基址(Segment Base Address)相加以生成最终的物理地址或虚拟地址。
  4. 线性地址(Linear Address):线性地址是逻辑地址到物理地址转换过程中的一个中间层次,在分段内存管理系统中通常用于表示内存访问的位置。线性地址是一个单调递增的地址空间,它通过将段基址与逻辑地址相加来生成。在分段和分页联合使用的内存管理系统中,线性地址先经过段式地址转换得到,然后通过分页机制映射到物理地址。

img
img
img

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Go语言开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以戳这里获取

)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Go语言开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以戳这里获取

  • 17
    点赞
  • 20
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值