【Linux】虚拟地址空间

1. 物理地址和虚拟地址定义

物理地址 (physical address): 放在寻址总线上的地址。放在寻址总线上,如果是读,电路根据这个地址每位的值就将相应地址的 物理内存中的数据放到 数据总线中传输。如果是写,电路根据这个地址每位的值就在相应地址的 物理内存中放入 数据总线上的内容。 物理内存是以 字节(8位)为单位 编址的。

虚拟地址 (virtual address): CPU启动 保护模式后,程序运行在虚拟 地址空间中。注意,并不是所有的“程序”都是运行在虚拟地址中。CPU在启动的时候是运行在实模式的,Bootloader以及内核在初始化页表之前并不使用虚拟地址,而是直接使用物理地址的。

2. 虚拟地址空间分布

在这里插入图片描述

2.1 内核空间

内核总是驻留在内存中,是操作系统的一部分。内核空间为内核保留,不允许应用程序读写该区域的内容或直接调用内核代码定义的函数。

2.2 栈(stack)
  • 栈是由高地址向低地址扩展的连续内存,栈的大小一般为 2M 或者 10M。

  • 栈内存是由系统分配,系统释放的,以函数为单位进行栈内存分配,函数栈帧,局部变量,形参变量等都存放在栈内存上。

  • 栈的内存分配释放速度快效率高,内存都是连续的。

2.3 堆(heap)
  • 堆是由低地址向高地址扩展的非连续内存,堆的大小影响的因素比较多,和系统虚拟内存的大小有关系。

  • 堆内存是由用户自己分配的,C 语言用 malloc/free进行分配释放,C++用 new/delete 进行分配释放,由于堆需要用户自己管理,因此堆内存很容易造成内存泄露,而栈内存不会。

  • 堆内存的分配释放相对于栈来说效率低一些,内存不一定连续,容易产生内存碎片,但是灵活性高。

2.4 BSS段

BSS(Block Started by Symbol)段中通常存放程序中以下内容

  • 未初始化的全局变量和静态局部变量

  • 初始值为0的全局变量和静态局部变量(依赖于编译器实现)

  • 未定义且初值不为0的符号(该初值即common block的大小)

2.5 数据段(Data)

数据段通常用于存放程序中已初始化且初值不为0的全局变量和静态局部变量。数据段属于静态内存分配(静态存储区),可读可写。

数据段保存在目标文件中(在嵌入式系统里一般固化在镜像文件中),其内容由程序初始化。例如,对于全局变量int gVar = 10,必须在目标文件数据段中保存10这个数据,然后在程序加载时复制到相应的内存。

2.6 代码段(text)

代码段也称正文段或文本段,通常用于存放程序执行代码(即CPU执行的机器指令)。

2.7 保留区

位于虚拟地址空间的最低部分,未赋予物理地址。任何对它的引用都是非法的,用于捕捉使用空指针和小整型值指针引用内存的异常情况。

3. 分段式存储

3.1 分段式存储定义

段式管理(segmentation),是指把一个程序分成若干个段(segment)进行存储,每个段都是一个逻辑实体(logical entity),程序员需要知道并使用它。它的产生是与程序的模块化直接有关的。段式管理是通过段表进行的,它包括段号或段名、段起点、装入位、段的长度等。此外还需要主存占用区域表、主存可用区域表。

3.2 分段式存储示例

假设有两个进程 A 和 B ,进程 A 所需内存大小为 10M ,其虚拟地址空间分布在 0x00000000 到 0x00A00000 ,进程 B 所需内存为 100M ,其虚拟地址空间分布为 0x00000000 到 0x06400000 。那么按照分段的映射方法,进程 A 在物理内存上映射区域为 0x00100000 到 0x00B00000 ,,进程 B 在物理内存上映射区域为 0x00C00000 到 0x07000000 。于是进程 A 和进程 B 分别被映射到了不同的内存区间,彼此互不重叠,实现了地址隔离。从应用程序的角度看来,进程 A 的地址空间就是分布在 0x00000000 到 0x00A00000 ,在做开发时,开发人员只需访问这段区间上的地址即可。应用程序并不关心进程 A 究竟被映射到物理内存的那块区域上了,所以程序的运行地址也就是相当于说是确定的了。
在这里插入图片描述

3.3 分段式存储优缺点
  1. 优点
    在段式存储管理中,每个段地址的说明为两个量:一个段名和一个位移。在段内,是连续完整存放的。而在段与段之间是不一定连续编址的。段名和位移构成了一种二维编址。 段式管理是不连续分配内存技术中的一种。其最大特点在于他按照用户观点,即按程序段、数据段等有明确逻辑含义的“段”,分配内存空间。克服了页式的、硬性的、非逻辑划分给保护和共享与支态伸缩带来的不自然性。 段的最大好处是可以充分实现共享和保护,便于动态申请内存,管理和使用统一化,便于动态链接。

  2. 缺点
    (1) 有内存碎片产生问题。
    (2) 在分段的映射方法中,每次换入换出内存的都是整个程序, 这样会造成大量的磁盘访问操作,导致效率低下。

4. 分页式存储

4.1 分页式存储定义

将各进程的虚拟空间划分成若干个长度相等的页(page),页式管理把内存空间按页的大小划分成片或者页面(page frame),然后把页式虚拟地址与内存地址建立一一对应页表,并用相应的硬件地址变换机构,来解决离散地址变换问题。页式管理采用请求调页或预调页技术实现了内外存存储器的统一管理。

4.2 分页式存储示例

一个可执行文件 (PE 文件 ) 其实就是一些编译链接好的数据和指令的集合,它也会被分成很多页,在 PE 文件执行的过程中,它往内存中装载的单位就是页。在 PE 文件的第一页包含了 PE 文件头和段表等信息,进程根据文件头和段表等信息,将 PE 文件中所有的段一一映射到虚拟地址空间中相应的页 (PE 文件中的段的长度都是页长的整数倍 ) 。这时 PE 文件的真正指令和数据还没有被装入内存中,操作系统只是根据 PE 文件的头部等信息建立了 PE 文件和进程虚拟地址空间中页的映射关系而已。当 CPU 要访问程序中用到的某个虚拟地址时,当 CPU 发现该地址并没有相相关联的物理地址时, CPU 认为该虚拟地址所在的页面是个空页面, CPU 会认为这是个页错误 (Page Fault) , CPU 也就知道了操作系统还未给该 PE 页面分配内存, CPU 会将控制权交还给操作系统。操作系统于是为该 PE 页面在物理空间中分配一个页面,然后再将这个物理页面与虚拟空间中的虚拟页面映射起来,然后将控制权再还给进程,进程从刚才发生页错误的位置重新开始执行。由于此时已为 PE 文件的那个页面分配了内存,所以就不会发生页错误了。随着程序的执行,页错误会不断地产生,操作系统也会为进程分配相应的物理页面来满足进程执行的需求。

4.3 分页式存储优缺点
  1. 优点
    (1) 由于它不要求作业或进程的程序段和数据在内存中连续存放,从而有效地解决了碎片问题。
    (2) 动态页式管理提供了内存和外存统一管理的虚存实现方式,使用户可以利用的存储空间大大增加。这既提高了主存的利用率,又有利于组织多道程序执行。

  2. 缺点
    (1) 要求有相应的硬件支持。例如地址变换机构,缺页中断的产生和选择淘汰页面等都要求有相应的硬件支持。这增加了机器成本。
    (2) 增加了系统开销,例如缺页中断处理机。
    (3) 请求调页的算法如选择不当,有可能产生抖动现象。
    (4) 虽然消除了碎片,但每个作业或进程的最后一页内总有一部分空间得不到利用果页面较大,则这一部分的损失仍然较大。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
### 回答1: Linux虚拟地址空间是指Linux操作系统为每个进程分配的虚拟地址空间,它包括用户空间和内核空间。用户空间是进程可以访问的地址空间,用于存储进程的代码、数据和堆栈等信息;而内核空间是操作系统内核可以访问的地址空间,用于存储操作系统内核的代码和数据等信息。虚拟地址空间的分配和管理是由操作系统内核负责的,它可以将物理内存映射到虚拟地址空间中,从而实现进程的内存管理和保护。 ### 回答2: Linux虚拟地址空间是指Linux内核和用户空间程序在运行时所使用的地址范围。Linux系统中,内核区和用户区是分开的,虚拟地址空间的大小也不一样。通常,在x86系统上,Linux虚拟地址空间大小为4GB,其中3GB分配给用户空间,1GB分配给内核空间。 对于用户空间的程序而言,它们认为整个4GB的地址空间都是可用的。但实际上,只有一部分是真正的物理内存,因为Linux系统支持虚拟内存管理技术,即将一部分虚拟地址空间映射到物理内存,另一部分映射到交换空间(Swap Space),当物理内存不足时,将一部分不常用的数据移到交换空间,以腾出更多的物理内存。 在用户区,虚拟地址空间通常被分为多个段,包括代码段、数据段、堆段、栈段等。不同的段用来存放不同类型的数据。例如,代码段存放程序的可执行代码;数据段存放程序中静态分配的全局变量和局部静态变量;堆段存放程序中通过动态内存分配函数(如malloc)创建的变量;栈段存放函数调用时所使用的局部变量。 在内核区,Linux也将虚拟地址空间分配为多层结构,以便于进行地址映射和管理。内核区的虚拟地址空间被用于管理Linux系统的硬件、设备、进程和文件等。内核区与用户区的分离可以提高系统的并发性和稳定性。 总之,Linux虚拟地址空间Linux系统中至关重要的一部分,它可以提高系统的安全性、并发性和可靠性,同时也为开发人员提供了更加灵活的编程方式。 ### 回答3: Linux虚拟地址空间是指操作系统为每个进程分配的用于存储其执行上下文所需信息的虚拟空间。它是一个非常重要的概念,因为它可以看作是针对每个进程的独立地址空间,而不必担心进程中其他进程会干扰它。 Linux虚拟地址空间通常被分为用户空间和内核空间两部分。其中,用户空间是用于存放进程代码和数据的空间,而内核空间则用于存放内核代码和内核数据的空间。这两个空间彼此隔离,进程无法访问内核空间,只能通过系统调用等方式请求内核的帮助。 Linux虚拟地址空间的大小通常由架构和编译器选项决定。在32位的x86架构中,进程通常只能访问2GB的虚拟地址空间,其中3GB用于用户空间,1GB用于内核空间。而在64位的x86_64架构中,进程可以访问2^48个虚拟地址空间,其中约128TB用于用户空间,剩余部分用于内核空间。 虚拟地址空间的映射可以被进程的二进制代码、共享库和动态创建的内存段所修改。这些映射是虚拟的,因为它们不一定与物理地址一一对应。Linux内核通过使用页表机制来将虚拟地址映射到物理地址。在页表中,每个虚拟页都有一个对应的页表项,页表项中存储了该虚拟页所映射的物理页的信息。 最后,通过Linux虚拟地址空间,操作系统可以轻松地进行进程间通信、内存隔离和安全控制等操作,从而使操作系统更加可靠和安全。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值