美文网首页
Linux 内存管理:虚拟内存空间布局

Linux 内存管理:虚拟内存空间布局

作者: 贪睡的企鹅 | 来源:发表于2019-07-19 12:22 被阅读0次

    虚拟内存布局

    Linux 内核给每个进程都提供了一个独立的虚拟地址空间,并且这个地址空间是连续的。这样,进程就可以很方便地访问内存,更确切地说是访问虚拟内存。虚拟地址空间的内部又被分为内核空间用户空间两部分,

    不同字长(也就是单个 CPU 指令可以处理数据的最大长度)的处理器,地址空间的范围也不同。32 位系统的内核空间占用 1G,位于最高处,剩下的 3G 是用户空间。而 64 位系统的内核空间和用户空间都是 128T,分别占据整个内存空间的最高和最低处,剩下的中间部分是未定义的。

    image

    用户态空间分布

    用户空间主要用来存储如下数据:

    • 程序代码
    • 全局变量
    • 常量字符串
    • 函数栈,存放方法局部变量
    • 堆,申请一小块内存,存放在堆中
    • glibc关联函数代码
    image

    Text Segment

    是存放二进制可执行代码的位置

    Data Segment

    存放静态常量,从高地址开始向下增长

    BSS Segment

    存放未初始化的静态变量

    malloc函数申请一小块内存,存放在堆中,从低地址开始向上增长

    mmap映射区

    • mmap用来存放malloc函数申请一大块内存区域,mmap不仅仅可以用来映射物理内存同时也可以用来映射文件,所谓映射文件就时将文件数据拷贝到物理内存中某个区域,这块区域通过页表映射到用户mmap映射区中。这样用户可以像访问内存一样访问文件。

    • 当mmap区域映射到文件时我们称为文件映射,非文件时称为匿名映射。

    • 当内存空间不足时可以将内存数据写入磁盘中的某个文件,这个过程称为换出,当进程访问这些内存时,再从磁盘读取这些数据到内存中这个过程称为换入。而这个写入的文件被称为swap文件

    image

    这块地址用来存放方法局部变量,从高地址开始向下增长

    内核态空间分布

    内核空间主要用来存储如下数据

    • 内核的代码要在内存里面;
    • 内核中也有全局变量;
    • 每个进程都要有一个 task_struct;
    • 每个进程还有一个内核栈;
    • 在内核里面也有动态分配的内存;
    • 虚拟地址到物理地址的映射表

    内核态的虚拟空间和某一个进程没有关系,所有进程通过系统调用进入到内核之后,看到的虚拟地址空间都是一样的。在内核态,32 位和 64 位的布局差别比较大,主要是因为 32 位内核态空间太小了。

    32位操作系统内核空间

    image
    直接映射区

    直接映射区,就是这一块空间是连续的,和物理内存是非常简单的映射关系,直接宏函数就得到物理内存的位置,大小为896M,其中前 1M 已经在系统启动的时候被占用,1M之后到896M主要用来存储内核代码内核的全局变量内核栈

    //运算规则 虚拟内存地址减去 3G,就得到物理内存的位置
    __pa(vaddr) 返回与虚拟地址 vaddr 相关的物理地址;
    __va(paddr) 则计算出对应于物理地址 paddr 的虚拟地址。
    
    内核动态映射空间 vmalloc区

    用来申请内核动态分配的内存(使用vmalloc函数)

    持久内核映射

    用来存储内核进程数据结构 task_struct

    固定映射区域

    主要用于满足特殊需求

    最后区域

    用户态的进程要映射一个文件到内存中,先要映射用户态进程空间的一段虚拟地址到物理内存,然后将文件内容写入这个物理内存供用户态进程访问。但对于操作系统而言能够操作硬件资源只能时操作系统内核来完成。

    image

    相关文章

      网友评论

          本文标题:Linux 内存管理:虚拟内存空间布局

          本文链接:https://www.haomeiwen.com/subject/dfmjlctx.html