目 录CONTENT

文章目录

内存

FatFish1
2024-11-21 / 0 评论 / 0 点赞 / 72 阅读 / 0 字 / 正在检测是否收录...

虚拟内存和物理内存

内存地址的概念

  • 物理地址:物理内存就是真实的内存,CPU的地址线可以直接进行寻址的内存空间大小。比如在32位平台下,寻址的范围是2^32也就是4G,即32位最高4G内存,并且这是固定的。

  • 虚拟地址:为了解决实际内存空间无法满足应用程序而但是的,经常用于容器化技术中,比如一个节点共有64G内存,部署了8个需要16G内存的pod。这时,每个pod都认为自己有16G的实际内存这一点是通过不断有目的的换入和换出(swap)实现的。这一部分内存就是虚拟内存。

    • 对于32位处理器,虚拟内存空间是4G,即每个pod/程序认为自己有4G内存,64位则更多

    • 每个pod/进程都认为自己得到的内存地址(虚拟内存)是连续的,而实际上,它通常是被分隔成多个物理内存碎片

    • 既然8个16G的pod需要的总内存是远超64G实际存储的,但是又要能够维持它的运行,那部分数据肯定是不能丢的,它其实被存储到了其他地方,例如本地硬盘,或外部磁盘存储器上,在需要时进行数据交换

由于存在两个内存地址,因此一个应用程序从编写到被执行,需要进行两次映射。第一次是映射到虚拟内存空间,第二次时映射到物理内存空间。在计算机系统中,第两次映射的工作是由硬件和软件共同来完成的。承担这个任务的硬件部分叫做存储管理单元MMU,软件部分就是操作系统的内存管理模块了

虚拟内存和物理内存的关联

虚拟内存和物理内存都被分成了大小相等的页,Linux下每个页为4KB。这样虚拟内存和物理内存就都有了页号这个概念,能够通过页号定位到内存中的特定页

虚拟内存中存的不是数据,而是页号+页内偏移量

这时只有再有一个虚拟内存页号与物理内存页号的对应关系,就可以通过虚拟内存找到对应的物理内存位置了。这个对应关系就是页表。程序读取内存时,通过页表和自己持有的虚拟内存页号,找到对应的物理内存页号,再结合记录的偏移量,确定物理内存中实际记录的数据

但是就像在容器化技术中,一个64G的节点部署了8台16G的pod,虚拟内存的页号肯定就比物理内存多,这时候程序在读取内存的时候,就会获得一个“缺页异常”,即申请的数据目前还不在物理内存中,此时CPU是不能工作的,Linux会产生一个hard page fault中断。系统需要从慢速设备(如磁盘)将对应的数据page读入物理内存,同时将一块最少使用的物理内存页,将他们写入慢速设备,然后修改页表映射关系

在linux中,这个用于额外存储的慢速设备就是交换区SWAP

  • swap in:产生hard page fault时从磁盘写回到物理内存

  • swap out:物理内存不够用时把一些物理内存页写入到磁盘

补图虚拟地址和物理地址-CSDN博客

用户空间和内核空间

以一个32位系统为例,一个程序认为自己拥有4G的内存空间,有3G是程序可以访问的,还有1G是只允许操作系统内核访问的,这两部分分别就是用户空间和内核空间,其作用为:

  • 用户空间:低3G字节(从虚拟地址 0x00000000 到 0xBFFFFFFF),提供给程序存储字节的业务数据对应的页号

  • 内核空间:高1G字节(从虚拟地址 0xC0000000 到 0xFFFFFFFF),提供给内核去支持CPU执行一些危险命令

内核态与用户态

其实就是程序运行在哪个地址空间中。运行在用户空间,就说程序是用户态,运行在内核空间,就说程序是内核态

DOS是不区分用户态和内核态的,即程序全部运行在内核态。而linux是区分的,这样提升了系统的稳定性

大部分代码是不具备内核态的能力的,少部分具备,例如NIO中的MappedByteBuffer

0

评论区