zoukankan      html  css  js  c++  java
  • Unix系统编程()虚拟内存管理

    在之前学到过进程的内存布局中忽略了一个事实:这一布局存在于虚拟文件中。

    因为对虚拟内存的理解将有助于后续对fork系统调用、共享内存和映射文件之类的主题阐述,这里还要学习一下有关虚拟内存的详细内容。

    Linux像大多数现代内核一样,采用了虚拟内存管理技术。

    该技术利用了大多数程序的一个典型特征,即访问局部性(locality of reference),以求高效使用CPU和RAM资源。

    大多数程序都展现了这两种类型的局部性。

    空间局部性(Spatial locality):是指程序倾向于访问在最近访问过的内存地址附近的内存(由于指令是顺序执行的,且有时会按顺序处理数据结构)。

    时间的局部性(Temporal locality):是指程序倾向于在不久后的将来再次访问最近刚访问过的内存地址(由于循环)。

    正是由于访问局部性特征,使得程序即便仅有部分地址空间存在于RAM中,依然可能得以执行。

    虚拟内存的规划之一是将每个程序使用的内存切割成小型的、固定大小的"页"(page)单元。

    相应的,将RAM划分成一系列与虚拟内存尺寸相同的页帧。

    任一时刻,每个程序仅有部分页需要驻留在物理内存页帧中。

    这些也构成了所谓驻留集(resident set)。

    程序未使用的页拷贝保存在交换区(swap area)内——这是磁盘空间中的保留区域,作为计算机RAM的补充——仅在需要时才会载入物理内存。

    若进程欲访问的页面目前并未驻留在物理内存中,将会发生页面错误(page fault),内核即刻挂起进程的执行,同时从磁盘中将该页面载入内存。

    在不同的系统中页帧的大小不一样,一般常见的4096、8192和16384字节等。

    为了支持这一组织方式,内核需要为每个进程维护一张页表(page table)。

    该页表描述了每页在进程虚拟地址空间(virtual address space)中的位置(可为进程所用的所有虚拟内存页面的集合)。

    页表中的每个条目要么指出一个虚拟页面在RAM中的所在位置,要么表明其当前驻留在磁盘上。

    在进程虚拟地址空间中,并非所有的地址范围都都需要页表条目。

    通常情况下,由于可能存在大段的虚拟地址空间并未投入使用,故而也无必要为其维护相应的页表条目。

    若进程试图访问的地址并无页表条目与之对应,那么进程将收到一个SIGSEGV信号。

    由于内核能够为进程分配和释放页(和页表条目),所以进程的有效虚拟地址范围在其生命周期中可以发生变化。

    这可能发生于如下场景。

    由于栈向下增长超出之前曾达到的位置。

    当在堆中分配或释放内存时,通过调用brk、sbrk或malloc函数族来提升program break的位置。

    当调用shmat连接System V共享内存区时,或当调用shmdt脱离共享内存区时。

    当调用mmap创建内存映射时,或者调用munmap解除内存映射时。

    image

    虚拟内存的实现需要硬件中分页内存管理单元(PMMU)的支持。PMMU把要访问的每个虚拟内存地址转换成相应的物理内存地址,当特定虚拟内存地址所对应的页没有驻留于RAM中时,将以页面错误通知内核。

    虚拟内存管理使进程的虚拟地址空间与RMA物理地址空间隔离开来,这带来许多优点。

  • 相关阅读:
    项目管理基本目录结构
    Linux 杀死所有进程
    PHP生成唯一固定长度邀请码
    ubuntu LNMP环境下安装Redis,以及php的redis扩展
    Ubuntu linux 返回上一次访问的目录
    ubuntu删除ppa源
    ubuntu1.8安装lnmp失败
    phpstorm更改sql文件匹配类型
    小程序组件概述
    小程序中WXSS样式控制
  • 原文地址:https://www.cnblogs.com/tuhooo/p/8667832.html
Copyright © 2011-2022 走看看