首页
学习
活动
专区
工具
TVP
发布
精选内容/技术社群/优惠产品,尽在小程序
立即前往

【Linux】翻山越岭——进程地址空间

操作系统会给每个进程创建地址空间,然后通过页表映射到物理内存,找到 虚拟空间。所以对于我们而言,直接使用虚拟地址,操作系统再从虚拟地址到页表加载到内存,在通过页表映射,找到对应的物理内存。...,那么操作系统会在物理内存上重新开辟一块新的内存空间,拷贝数据,然后在修改映射关系,不再指向老的变量,在整个修改的过程中,和父子进程的虚拟地址没有任何关系,只是底层经过页表映射到不同的区域,所以我们看到了地址是一样的...;对于磁盘程序内部的地址称为逻辑地址,在Linux下,虚拟地址到线性地址、逻辑地址是一样的,但在其他地方,区分比较明确, ---- 二、为什么 了解了进程地址空间是什么了以后,那为什么存在进程地址空间呢...让进程以统一的视角,看待进程对应的代码和数据各个区域,方便编译器也以统一的视角来进行编译代码 可执行程序被编译器编译的时候每个代码和数据在内存中已经有虚拟地址了(在磁盘上称为逻辑地址),也就是说...也就是在整个CPU运行过程中,CPU并没有见到物理地址,用的都是虚拟地址。 另外,对于磁盘内可执行程序编译好,这个可执行程序的地址不叫虚拟地址,是逻辑地址。

75930

【Linux】借命令行参数的引导,探索环境变量的奥秘

父进程和子进程地址都不变,但是经过页表映射关系访问了不同的内存,所以打印出来的值是不一样的 上面的图就足以说明问题: 同一个变量,地址相同,其实是虚拟地址相同,内容不同其实是被映射到了不同的物理地址...3.3.地址空间的原理 地址空间相当于就是操作系统给每一个进程画的大饼,所以并不会直接在物理内存中开辟空间,而是会用虚拟地址,当这个进程真正需要利用内存的时候,才会通过页表将虚拟内存映射到物理内存当中。...在虚拟地址申请的内存空间不会立刻给你在屋里内存中申请,而是会等待你真正需要内存空间的时候才会在物理空间中开辟,地址空间相当于是一个支票,等到你需要的时候才会给你真正的申请空间 3.4.为什么要有地址空间...是在物理内存中存放的。 页表的最大作用就是将地址空间上的地址(虚拟/线性)转化到物理内存当中!...我们当用malloc申请空间时,我们其实并没有在地址空间中申请,而是在地址空间上开辟空间,我们经过页表+物理内存映射,但是我们当前并没有建立映射关系,就会出现缺页中断!

12010
  • 您找到你想要的搜索结果了吗?
    是的
    没有找到

    进程地址空间

    虽然打印出来的地址是一样的,但是这绝对不是真的地址,只是一个假的地址,说明打印出来的地址并不是在物理内存上的地址! 在Linux地址下,这种地址叫做 虚拟地址。...那不就会出现程序异常的情况吗?那么我们前面也提到了操作系统也会将虚拟地址转化为内存物理地址,那么如何将其转化为物理地址呢? 通过我们的原理就知道了! 进程地址空间的原理 页表!...页表是一种数据结构,他就类似于哈希表,是采用一种映射的方式,将虚拟地址映射到物理内存上,然后获取真正的物理地址 给出一张图大家就可以明白了 当虚拟地址时非法地址时,我们的页表就禁止映射到物理内存上...那么大家想一想,当我们在C语言或者C++中,申请一块空间时,是真正直接在物理内存上开辟一块空间吗? 答案是不是!...其实我们申请空间本质上是在虚拟地址空间上申请空间,等到真正需要对内存进行访问时,才在物理内存上申请空间,同时操作系统自动完成建立页表等任务。

    8010

    Linux进程概念(三)

    在打开Linux的时候bash因为要处理用户的命令,这些命令也是程序,运行程序需要指定路径,所以操作系统就提前将这些指令的路径放在了专属的配置文件,在启动操作系统时将这个文件导入内存中形成一个内存级变量...虚拟空间是操作系统防止用户把物理内存给玩坏所弄出来的空间,是通过页表来进行映射和管理的: 在32位的机器中,操作系统会给每个进程“画个大饼”,说你们每个进程都可以分配到2^32字节(约等于4GB)的空间大小...进程在运行的时候有自己的虚拟地址空间,然后通过页表来映射到物理内存上的。 这些都是由操作系统完成的。 这也就能解释刚开始代码为什么是显示的是同一个地址,子进程改变了数值父进程却没有改变。...,但是页表会发现原本映射出来的位置已经被占有了,这个时候就会在另一处先开辟空间,然后拷贝父进程在内存中的内容到新开辟的空间当中,然后更改页表的映射,这个叫做写时拷贝,这样父进程和子进程就是两个完全独立的空间...CPU的寄存器中储存的就是虚拟地址,通过main函数的虚拟地址然后找到内存中的main然后解析代码,然后调用fun的时候又通过页表映射到了进程地址空间当中,CPU又拿到了fun函数的虚拟地址,然后再映射到物理内存当中

    56500

    初识Linux · 地址空间

    ,我们创建一个父进程之后,在父进程里面创建一个子进程,子进程要完成的工作是打印g_val和它的地址,当count到5的时候就修改g_val,但是后续还是要一直打印,父进程要做的工作就是一直打印g_val...我们平常写下的对某个对象取地址,本质上都是在虚拟内存层面上进行操作,并不是在物理内存上,那么上面代码写的,&g_val本质上就是个虚拟地址! 那么虚拟地址(内存)如何和物理地址(内存)进行联系呢?...我们最开始的问题是,虚拟内存如何和物理内存进行联系的,这个过程有地址空间的一份功劳,我们从名字来看,地址空间,地址,空间,容易想到这是一块空间,空间里面充满了地址这种描述,实际上确实是这样的,地址空间在源码中的名字叫做...页表,最直观的就是: 最最最简单的页表就是这样,每一行的元素存在映射关系,既然是提到了映射关系,相信不少同学都明白了,映射嘛,左边是虚拟地址,右边是物理地址,这就是OS通过页表,地址空间等,链接了虚拟内存和物理内存的方法...现在就得出结论:虚拟内存和物理内存的联系是通过页表,地址空间,从地址空间得到虚拟内存,在页表存在虚拟内存和物理内存的映射的关系来找到对应的数据,这是OS中找数据的方法。

    7810

    内存映射技术分析

    考虑到MMIO比PIO复杂很多,涉及更多的概念,作者打算先分析几篇基本的Linux的内存管理概念,再来分析MMIO。 作者大概想了一下,主要由这几篇构成: 1,虚拟内存管理和内存映射。...在protected mode下,访问的虚拟内存,如果访问0x1234这个虚拟地址,那么可能物理上是0xabcde234;从虚拟地址到物理的转换,是通过MMU完成的。 使用虚拟内存后的好处是什么呢?...据一位懂BIOS的人和我说,BIOS中也可以配置一次,再做一次映射~ 5,内存映射 看上面例子中的虚拟地址空间,和物理地址范围,二者其实不是对应的。...linux会组织起来一个数据叫做page table(传说中的页表),把虚拟内存和物理内存之间的映射关系保存到page table中,再把page table的地址告诉MMU,MMU就可以在CPU访问虚拟地址的时候...6,/dev/mem busybox提供了一个命令---devmem。可以通过devmem直接查看或者修改物理内存。作者在这里在唠叨一下,busybox的代码比较短小精悍,非常不错,值得阅读!

    2.3K110

    【Linux】进程概念(下)

    其实除了上面空间分布中的区域外,还有一些我们还没学,所以我们以后再介绍,但是在栈区上面有两个是我们刚学习的区域,就是命令行参数和环境变量。 所以我们上面学的空间分布,它到底是什么呢?它是内存吗?...在操作系统中,为了让进程找到物理内存中自己的数据,会为每个进程维护一张映射表,它要为进程地址空间和物理内存之间构建一种映射关系,而这个表叫做页表。...它的左侧放的是虚拟地址,右侧是数据在物理内存中的地址,它们两者之间是一种映射关系。...,例如 1/0 表示是/否分配有内存,1/0 表示 是否在内存中有内容;例如下图: 当我们的进程拿着一个虚拟地址来找物理地址的时候,假设这时候内存还没有给它分配物理地址,此时操作系统就会把该进程暂停,并从磁盘中加载相对应的程序到内存中...最后,通过页表,还可以让进程映射到不同的物理内存中,从而实现进程的独立性! 5.

    17210

    【Linux】进程详解:命令行参数、环境变量及地址空间

    为了防止用户破坏系统中的空间,真正存储变量的空间由操作系统统一管理 所以上面&gval其实打印出来的是虚拟的地址空间,虚拟地址空间通过一系列的翻译转化可以通过「页表」映射到真正的物理地址空间,而子进程中的...这些虚拟地址在进程运行时由操作系统通过页表等机制映射到实际的物理地址上。...这些虚拟地址通过页表和物理内存建立映射的联系。由于虚拟地址也是有0x00000000到0xffffffff线性增长的,所以虚拟地址也叫作「线性地址」。...和mm_struct,父子进程的进程地址空间当中的各个虚拟地址分别通过页表映射到物理内存的某个位置 一开始创建子进程的时候,子进程和父进程的代码和数据共享,即相同的虚拟地址会映射到相同的物理地址空间 当在子进程要修改父进程中的数据的时候...所以任意一个进程,可以通过地址空间+页表可以将乱序的内存数据,变成有序,分门别类的规划好,并且可以使得用户不能接触到物理内存,这样就不会出现系统级别(访问物理内存)的越界问题了,因为虚拟内存的越界问题并不会影响到实际的物理内存

    14010

    【Linux】从虚拟到物理:解密地址空间的奥秘

    背景知识 在早期的时候,计算机还没有虚拟机制,程序指令所访问的内存地址就是物理地址,所以就要将所有程序都加载到内存中,但是我们实际的物理内存是有限的,那么就会出现一些问题: 当多个程序重新运行时,必须保证这些内存用到的内存总量小于计算机实际的物理内存的大小...虚拟地址与物理地址的关系 在上文我们已经看到了操作系统是存在着虚拟地址和物理地址的,也得知了它们之间存在着一种映射关系,那么它们间又是怎么进行映射的呢?...为了讲清楚这个关系,我画了一张图: 这是上面程序中子进程与父进程在操作系统中的逻辑图。 可以看到,虚拟地址是通过页表来映射到物理内存的。 那么页表的具体结构是什么呢? 3....那么你认为在计算机中的页表是如何让虚拟地址映射物理地址的。是一一对应的关系吗? 假设是一一对应的关系: 如果在极端情况下,每个地址都在页表中建立映射关系,其中页表的每一列大小都是4字节。...4.总结 虚拟地址的存在使得用户在引发异常操作时,操作系统能在差页表阶段就发现拦截,而不是等到真正影响到物理内存时才报错。

    10610

    Linux 内存性能指标

    内存基础概念 先执行一下 top 命令,看结果中关于内存的相关部分 # top 其中的 VIRT、RES、SWAP 都是什么呢?...分别是下面的3个概念 物理内存 Resident - RES 实际的内存空间 RAM 交换区 Swapped - SWAP 当物理内存不足时,操作系统会把内存中不常用的页换出到磁盘空间 当被换出的页需要被访问时...,再换入到物理内存 所以交换区就是用来临时存放内存中不常用的内容的,感觉就想内存的一个小仓库 虚拟内存 Virtual - VIRT 虚拟内存 = 物理内存 + 交换区 程序操作内存时,实际就是操作虚拟内存中的地址...,操作系统再负责映射到物理地址,或者交换区 快速了解内存状态 # free 主要指标 total - 物理内存总大小 used - 已经使用的物理内存大小 free - 空闲的物理内存...,需要到磁盘中找 所以较多的主缺页中断意味着较多的访问磁盘 可以通过 sar 命令查看指标 # sar -B 1 3 pgpgin/pgpgout 就是内存的换入换出 fault 次缺页中断

    2.4K50

    【Linux修炼】10.进程地址空间

    即如果内存中的某一个位置c=10,当我们编写代码时,代码的数据首先会被加载到虚拟地址中,通过页表的映射,映射到了相应的物理地址,假设机缘巧合下恰好映射到了如上图的位置,就会将原有的数据修改为新的数据,而这个映射的虚拟地址和物理地址之间也肯定是不同的...(毕竟一个是虚拟的,一个是物理的) 因此我们能做的,就是编辑代码让其在虚拟地址上保存,而通过页表映射到内存等其他的所有工作,都是由操作系统自动帮你完成的。...global_val,于是global的内存中的地址就会通过页表映射到虚拟空间的某一个地址中,于是父进程和子进程就可以通过虚拟空间中的地址去访问global,并且打印时父进程和子进程对应的global对应的虚拟地址也是相同的...(在Linux下,虚拟地址和逻辑地址是一样的。) 先来个灵魂拷问:当我们写了一个程序在磁盘中,当他未载入到磁盘时,其内部的函数和变量有地址吗? 答案当然是肯定的。...原因与上述的理解相同,那么此时在cpu中执行完了main()函数,通过找到的fun()函数的虚拟地址再次原路返回映射到内存,这时候CPU就调用了内存中fun()函数的代码,因为内存中的fun()函数的代码才是实际存在的

    1.2K00

    MIT 6.S081 Lab Three -- 页表

    不要打印无效的PTE。 在上面的示例中,顶级页表页具有条目0和255的映射。 条目0的下一级只映射了索引0,该索引0的下一级映射了条目0、1和2。 您的代码可能会发出与上面显示的不同的物理地址。...page 2中是什么?在用户模式下运行时,进程是否可以读取/写入page 1映射的内存?...内核页表直接映射(恒等映射)到物理地址,也就是说内核虚拟地址x映射到物理地址仍然是x。Xv6还为每个进程的用户地址空间提供了一个单独的页表,只包含该进程用户内存的映射,从虚拟地址0开始。...页表设置中的错误可能会由于缺少映射而导致陷阱,可能会导致加载和存储影响到意料之外的物理页存页面,并且可能会导致执行来自错误内存页的指令。...,而内核态页表映射的物理内存不用释放,因为内核态映射的物理内存是和内核进程,以及其他所有进程共享的。

    36741

    MIT 6.S081 Lab Five -- Lazy Page Allocation

    Xv6应用程序使用sbrk()系统调用向内核请求堆内存。在我们给出的内核中,sbrk()分配物理内存并将其映射到进程的虚拟地址空间。内核为一个大请求分配和映射内存可能需要很长时间。...当进程第一次尝试使用延迟分配中给定的页面时,CPU生成一个页面错误(page fault),内核通过分配物理内存、置零并添加映射来处理该错误。 您将在这个实验室中向xv6添加这个延迟分配特性。...处理sbrk()参数为负的情况。 如果某个进程在高于sbrk()分配的任何虚拟内存地址上出现页错误,则终止该进程。 在fork()中正确处理父到子内存拷贝。...正确处理fork的内存拷贝:fork调用了uvmcopy进行内存拷贝,所以修改uvmcopy如下 //将父进程页表内容拷贝一份到子进程页表中,包括物理内存 int uvmcopy(pagetable_t...copyin函数,从addr用户空间的虚拟地址处,拷贝指定大小的数据到ip内核态虚拟地址处 copyin函数中,会先调用walkaddr函数,通过遍历用户态页表,完成用户态空间的虚拟地址到物理地址的翻译过程

    28541

    linux进程地址空间

    状态寄存器:status 在我们的CPU里面,一定会存在很多的寄存器,我们的CPU里面的寄存器扮演的角色是什么:寄存器也具有对于数据的保存能力,把进程的高频的内容数据放到寄存器里面去,方便我们的CPU管理...,怎么可能一个变量一个地址,但是这个变量的数值却不一样,这个就是因为这个打印的结果不是真实的物理地址,而是我们的虚拟地址; 3.3页表概念的引入 页表是一张显示这个虚拟地址和真真实的物理地址的关系的映射表...)因此这个父进程的变量在子进程里面也是存在的,但是因为这个进程具有独立性,因此这个会发生写实拷贝,这个物理地址会发生变化,开辟新的物理地址去存储这个修改后的变量的数值; 因此这个上面的打印结果,打印的是虚拟地址...,因为地址空间使得所有的进程都需要虚拟地址,子进程和父进程的关系,调度是一套统一的流程; 当我们访问内存的时候,会增加一个转换的过程,在这个转换的过程中,虚拟地址空间会进行审查,例如我们对于这个只读区域进行修改...,显然是不符合要求的,这个时候的地址空间就会进行这个请求的拦截,防止其进入物理内存,在某些程度上面保护了物理内存; 3.7页表 CPU里面的这个cr3寄存器把这个进程的页表的起始地址进行管理和存储,因此我们进行进程切换的时候

    4610

    MongoDB与内存

    先讲讲Linux是如何管理内存的 在Linux里(别的系统也差不多),内存有物理内存和虚拟内存之说,物理内存是什么自然无需解释,虚拟内存实际是物理内存的抽象,多数情况下,出于方便性的考虑,程序访问的都是虚拟内存地址...很多人会把虚拟内存和Swap混为一谈,实际上Swap只是虚拟内存引申出的一种技术而已:操作系统一旦物理内存不足,为了腾出内存空间存放新内容,就会把当前物理内存中的内容放到交换分区里,稍后用到的时候再取回来...再说说MongoDB是如何使用内存的 目前,MongoDB使用的是内存映射存储引擎,它会把数据文件映射到内存中,如果是读操作,内存中的数据起到缓存的作用,如果是写操作,内存还可以把随机的写操作转换成顺序的写操作...faults 940g 1893g 21.9g 0 其中内存相关字段的含义是: mapped:映射到内存的数据大小 visze:占用的虚拟内存大小 res:占用的物理内存大小 注:如果操作不能在内存中完成...如果想验证这一点,可以在开启或关闭journal后,通过pmap命令来观察文件映射情况: shell> pmap $(pidof mongod) 到底MongoDB配备多大内存合适?

    69630

    iOS底层原理——启动优化及其原理

    1.1 打印应用启动时间 我们在工程设置中添加 DYLD_PRINT_STATISTICS,DYLD_PRINT_STATISTICS_DETAILS打印启动信息。...关于启动优化的需要了解的概念 我们进行启动优化就要了解下相关的概念,以便我们了解其实现的原理。 2.1 物理内存和虚拟内存 在最早开发中,我们程序在操作系统中运行。...这样,只要我们能够妥善的控制这个虚拟地址到物理地址的映射过程,就可以保证任意一个程序所能访问的物理内存区域更另外一个程序互相不重叠,达到地址空间隔离的效果。 虚拟地址空间是指虚拟的。...目前在iOS中一页的大小是16k,Mac(PAGESIZE命令)上是4k。虚拟空间的页叫作虚拟页,物理空间的页叫作物理页,磁盘中的页叫作磁盘页。...这个时候CPU要执行代码会中断掉,操作系统会把需要的数据加载到物理内存中,哪里有空闲位置就插入到这里,一般来说,手机启动后一段时间,基本没有空闲位置,操作系统会通过页面置换算法覆盖掉不活跃的内存 虚拟存储的实现需要硬件的支持

    66110

    十问 Linux 虚拟内存管理 ( 一 )

    Linux 的虚拟内存管理有几个关键概念: 每个进程有独立的虚拟地址空间,进程访问的虚拟地址并不是真正的物理地址 虚拟地址可通过每个进程上页表与物理地址进行映射,获得真正物理地址 如果虚拟地址对应物理地址不在物理内存中...,则产生缺页中断,真正分配物理地址,同时更新进程的页表;如果此时物理内存已耗尽,则根据内存替换算法淘汰部分页面至物理磁盘中。...其中堆顶的位置可通过函数 brk 和 sbrk 进行动态调整。 文件映射区域 :如动态库、共享内存等映射物理空间的内存,一般是 mmap 函数所分配的虚拟地址空间。...用户空间由低地址到高地址仍然是只读段、数据段、堆、文件映射区域和栈 二.malloc 是如何分配内存的?...我们知道, malloc 分配的的内存是虚拟地址空间,而虚拟地址空间和物理地址空间使用进程页表进行映射,那么分配了空间就是占用物理内存空间了吗?

    11.4K23

    从进程栈内存底层原理到Segmentation fault报错

    pte_offset_map(pmd, address); return handle_pte_fault(mm, vma, address, pte, pmd, flags); } Linux 是用四级页表来管理虚拟地址空间到物理内存之间的映射管理的...我们今天讨论的主题是栈内存,这个对应的是匿名映射页处理,会进入到 do_anonymous_page 函数中。...关于伙伴系统我们之前在内核内存管理 这篇文章中详细介绍过,感兴趣的同学可以移步到该文中详细了解。 到了这里,开篇的问题一就有答案了,堆栈的物理内存是什么时候分配的?...第二,当进程在运行的过程中在栈上开始分配和访问变量的时候,如果物理页还没有分配,会触发缺页中断。在缺页中断中调用内核的伙伴系统真正地分配物理内存。...在回顾和总结下开篇我们抛出的三个问题: 问题一:堆栈的物理内存是什么时候分配的?进程在加载的时候只是会给新进程的栈内存分配一段地址空间范围。

    80820

    iOS的文件内存映射——mmap

    前言 mmap在日常开发中偶尔会遇到的一个关键词,最常用到的场景是MMKV,其次用到的是日志打印。虽然都已经被封装好,但也需要了解下mmap的基本原理和过程。...正文 进程是App运行的基本单位,进程之间相对独立。iOS系统中App运行的内存空间地址是虚拟空间地址,存储数据是在各自的沙盒。...在操作系统层面,当App读取一个文件时,实际是有两步:先将文件从磁盘读取到物理内存,再从系统空间拷贝到用户空间(可以认为是复制到系统给App统一分配的内存)。...而mmap将磁盘上文件的地址信息与进程用的虚拟逻辑地址进行映射,建立映射的过程与普通的内存读取不同:正常的是将文件拷贝到内存,mmap只是建立映射而不会将文件加载到内存中。...总结 mmap就是文件的内存映射,通常读取文件是将文件读取到内存,会占用真正的物理内存;而mmap是用进程的内存虚拟地址空间去映射实际的文件中,这个过程由操作系统处理。

    2.7K10

    【Linux】从零开始认识进程 — 终篇

    HELLO在Bash中是存在的,只是没有把它当做环境变量。...物理地址,用户一概看不到,由OS统一管理 2.2 概念认识 其实我们常说的地址并不是在磁盘或内存中的真正的地址,程序地址空间是在操作系统中来说的。...操作系统会检查该变量是不是子进程独有的,如果不是,那么就会重新开辟一个物理空间来储存新值,对应的页表映射也发生改变,注意页表的虚拟地址不变,改变的是映射的物理空间,就能够修改变量值了,而且打印的虚拟空间一致...而通过页表来进行映射,就明确了储存地址的范围,保证了数据读取的安全: 将无序变有序,让进程以统一 的视角来看待物理内存,以及自己运行的各个区域! 拦截非法请求,保护物理内存空间!...操作系统可以进行一下检查: 检查是不是在物理内存中(缺页中断,页表中不存在物理内存,会重新开辟空间) 检查是不是数据需要写时拷贝(发生写时拷贝) 如果都不是就进行异常处理。

    12610
    领券