网站不在首页显示出来,谷歌网站提交入口,免费app大全下载,做报名表的网站虚拟内存
虚拟内存是一种操作系统提供的机制#xff0c;用于将每个进程分配的独立的虚拟地址空间映射到实际的物理内存地址空间上。通过使用虚拟内存#xff0c;操作系统可以有效地解决多个应用程序直接操作物理内存可能引发的冲突问题。
在使用虚拟内存的情况下#xff0…虚拟内存
虚拟内存是一种操作系统提供的机制用于将每个进程分配的独立的虚拟地址空间映射到实际的物理内存地址空间上。通过使用虚拟内存操作系统可以有效地解决多个应用程序直接操作物理内存可能引发的冲突问题。
在使用虚拟内存的情况下每个进程都有自己的独立的虚拟地址空间它们不能直接访问物理内存地址。当程序访问虚拟内存地址时操作系统会进行地址转换将虚拟地址映射到物理地址上这样不同的进程运行时写入的是不同的物理地址避免了互相覆盖指针的问题。
虚拟内存的使用使得每个进程都可以拥有相同的虚拟地址空间而不用担心与其他进程的地址冲突。操作系统负责管理虚拟地址和物理地址之间的映射关系并在需要时进行地址转换。这样进程可以以一种透明的方式访问内存无需关心内存的实际物理位置。 通过虚拟内存机制操作系统能够更好地管理系统内存资源提供更高的安全性和稳定性。它可以为每个进程提供独立的地址空间保护进程间的数据隔离同时也可以有效地利用物理内存将不常用的数据交换到磁盘上(交换区)以提供更大的可用内存空间。
内存分段
在分段机制下虚拟地址由两部分组成段选择子和段内偏移量。段选择子是一个索引用于指定要访问的段的起始地址和长度。段内偏移量则表示在该段内的具体位置。
操作系统会维护一个段表其中包含了每个段的起始地址和长度信息。当程序访问一个虚拟地址时操作系统会通过段选择子从段表中找到对应的段描述符然后根据段描述符中的信息计算出物理地址。
具体的映射过程如下
程序访问虚拟地址通过段选择子找到对应的段描述符。根据段描述符中的基址和长度信息计算出段的起始物理地址。将段的起始物理地址与段内偏移量相加得到最终的物理地址。 不过需要注意的是分段机制可能会导致内存碎片的问题因为不同段的大小可能不同导致一些碎片化的空间无法被利用。当不够内存分配的时候会选择使用内存交换先把一块正在使用的内存移到磁盘中然后再移回来把中间留的内存缝隙全用上虽然解决了内存碎片的问题但是这个交换操作很慢效率低看下图示 虚拟内存、分段和内存交换似乎解决了同时运行多个程序的问题但仍存在性能瓶颈。由于硬盘访问速度较慢每次内存交换都需要将大段连续的内存数据写入硬盘。因此如果交换的是占用大量内存空间的程序整个系统会变得卡顿。
为了解决内存分段的碎片和提高内存交换效率引入了内存分页机制。
内存分页
内存分页是将整个虚拟和物理内存空间划分为固定大小的连续内存块称为页Page。在Linux下每一页的大小通常为4KB。虚拟地址与物理地址之间通过页表进行映射页表存储在CPU的内存管理单元MMU中从而CPU可以直接通过MMU找到实际访问的物理内存地址。
虚拟地址与物理地址之间通过页表来映射如下图 由于内存空间事先划分为固定大小的页不会像分段机制那样产生碎片。当释放内存时以页为单位进行释放避免了无法利用的小内存块。
如果内存空间不足操作系统会将其他正在运行的进程中的最近未使用的内存页面暂时存储到硬盘上称为换出Swap Out。当需要时再将页面加载回内存称为换入Swap In。因此每次写入硬盘的是少量的一页或几页不会花费太多时间从而提高了内存交换的效率。 简单分页
简单分页存在空间上的缺陷。在操作系统可以同时运行大量进程的情况下页表会变得非常庞大。在32位环境下虚拟地址空间为4GB假设页的大小为4KB就需要大约100万个页。每个页表项需要4字节来存储所以整个4GB空间的映射需要4MB的内存来存储页表。
尽管4MB的页表看起来并不算太大但要注意每个进程都有自己的虚拟地址空间也就是说每个进程都有自己的页表。如果有100个进程就需要400MB的内存来存储页表这对于内存来说是相当大的开销更不用说64位环境下了。
多级页表
要解决上述问题我们可以采用一种叫做多级页表Multi-Level Page Table的解决方案。在之前我们已经了解到在32位环境下页大小为4KB的情况下一个进程的页表需要存储100多万个页表项每个项占用4字节的空间因此一个页表需要4MB的内存空间。
为了节省内存空间我们可以将单级页表进行分页将一个页表一级页表分为1024个页表二级页表每个二级页表包含1024个页表项形成二级分页结构。这样一级页表覆盖整个4GB的虚拟地址空间而对于未使用的页表项不会创建对应的二级页表只在需要时才创建。如下图所示 换个角度来看大多数程序未使用到整个4GB的虚拟地址空间因此部分页表项是空的没有分配实际的内存空间。在物理内存紧张的情况下操作系统会将最近一段时间未访问的页表换出到硬盘从而释放物理内存。使用二级分页一级页表只需要覆盖整个4GB的虚拟地址空间而未使用的页表项不需要创建对应的二级页表。假设只有20%的一级页表项被使用那么页表占用的内存空间只有0.804MB相比于单级页表的4MB内存节约非常巨大。
为什么不分级的页表无法实现这样的内存节约呢从页表的性质来看页表保存在内存中其主要作用是将虚拟地址翻译为物理地址。如果在页表中找不到对应的页表项计算机系统将无法正常工作。因此页表必须覆盖整个虚拟地址空间。而不分级的页表需要100多万个页表项进行映射而二级分页只需要1024个页表项一级页表覆盖整个虚拟地址空间二级页表在需要时创建。
页表缓存TLBTranslation Lookaside Buffer
TLBTranslation Lookaside Buffer是一个位于CPU芯片中的缓存用于存储程序中最常访问的页表项以加快虚拟地址到物理地址的转换速度。多级页表虽然解决了空间上的问题但是增加了转换的工序导致时间上的开销。然而由于程序的局部性原理程序执行期间通常仅限于某一部分访问的存储空间也局限于某个内存区域。因此通过将最常访问的页表项存储到TLB这个硬件缓存中可以更快地进行地址转换。
在CPU芯片中内存管理单元Memory Management Unit芯片负责处理地址转换和TLB的访问与交互。当CPU进行寻址时首先会查找TLB如果找到了对应的页表项就可以直接进行物理地址的访问避免了继续查找常规页表的开销。
由于TLB中存储的是程序最常访问的几个页表项所以TLB的命中率通常是很高的。这是因为程序执行过程中访问的页表项相对固定。通过利用TLB可以大大提高地址转换的速度加快程序的执行效率。
Linux内存管理 Linux内存管理涉及逻辑地址和线性地址的转换。逻辑地址是程序使用的地址而线性地址是通过段式内存管理映射的地址也称为虚拟地址。
Linux的虚拟地址空间分为内核空间和用户空间两部分。32位系统中内核空间占用1G剩下的3G是用户空间64位系统中内核空间和用户空间都是128T分别占据内存空间的最高和最低处。如下所示 进程在用户态时只能访问用户空间内存进入内核态后才能访问内核空间内存。虽然每个进程都有独立的虚拟内存但虚拟内存中的内核地址关联的是相同的物理内存这样进程切换到内核态后就可以方便地访问内核空间内存。
总结
虚拟内存是操作系统提供的一种机制通过将每个进程分配的独立的虚拟地址空间映射到实际的物理内存地址空间上解决了多个应用程序直接操作物理内存可能引发的冲突问题。虚拟内存的使用使得每个进程都可以拥有相同的虚拟地址空间而不用担心与其他进程的地址冲突。通过虚拟内存机制操作系统能够更好地管理系统内存资源提供更高的安全性和稳定性。虚拟内存的实现方式有分段和分页其中分页机制更为常用采用多级页表的方式节约了内存空间。页表缓存TLB能够加快虚拟地址到物理地址的转换速度。Linux的内存管理涉及逻辑地址和线性地址的转换将虚拟地址空间分为内核空间和用户空间方便进程访问内核空间内存。 我是努力的小雨一名 Java 服务端码农潜心研究着 AI 技术的奥秘。我热爱技术交流与分享对开源社区充满热情。同时也是一位掘金优秀作者、腾讯云内容共创官、阿里云专家博主、华为云云享专家。 我将不吝分享我在技术道路上的个人探索与经验希望能为你的学习与成长带来一些启发与帮助。 欢迎关注努力的小雨