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

进程地址空间

程序地址空间   我们在学习C/C++的时候我相信大部分人都见过下面这张图:   有一些细微的差别,但是并不影响,按照正常人的逻辑思维方式低地址放在下面,高地址放在上面。...可以发现进程将 g_val 的更改之后,为什么进程的 g_val 却没有变?难道是写时拷贝?但是他们的地址一模一样,明明是同一个变量啊!!   ...而进程创建进程的时候,进程继承进程这个表的,当进程对 g_val 的值进行修改,并不能从父进程的表中对应物理地址进行修改,因为进程是具有独立性的!   ...所以,进程需要再内存中单独开辟另一块空间用来存储修改过的 g_val ,但是这是进程和进程虽然 g_val 虚拟地址相同,物理地址却不同了,所以就能看到 “同一个变量有两个值” 的现象。...系统给我们提供一张虚拟地址和物理地址的映射表——页表(Page tables) ✏️总结  我们了解了程序地址空间各个区域有什么,并且他们是什么顺序存放的,而在进程对全局变量做修改与进程得到两个不同的结果

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

进程地址空间

文章目录 一.感性理解进程地址空间 二.理性认识进程地址空间 1.虚拟和物理地址空间 2.虚拟地址和物理地址联系 a.页表映射 b.写时拷贝 三.为什么要存在进程地址空间 在正式开始之前我们首先来看这样的一个现象...父子进程(父子进程谁先运行,这个不确定,由调度器决定)更改以前打印的都是同一个地址同一个值这很好理解,进程在改变了全局变量的值以后,父子进程输出的值不一样了也勉强可以理解,因为进程之间具有独立性...那么老板必须要记得他给每个员工画的饼是怎么样的,如果今天和昨天画的饼不一致,这个老板可能失去员工们的信任。所以老板在管理员工的同时,还要管理自己画的饼。...}; 二.理性认识进程地址空间 进程之间是共享CPU和主存资源的,但随着对CPU需求的增长,太多的进程需要太多的资源,有些进程就可能会卡死,此外如果某一个进程发生了越界,就会影响到别的进程的存储器。...页表会将虚拟地址中和数据的物理地址建立连接,当需要访问数据时,页表根据虚拟地址对应的物理地址去物理内存中查找需要的数据。

65930

【Linux】地址空间&&虚拟地址

进程会把进程的很多数据结构全拷贝一份,基本上进程的PCB、地址空间和页表基本上和进程的一致。...进程的地址空间也会有一个虚拟地址进程对应的页表也来自进程,所以页表保存的地址,从而进程也会指向那个g_val。...而进程本身在运行的时候具有独立性,所以进程对数据进行修改,就不能影响进程,所以当进程尝试对数据进行修改时,操作系统发现进程也有,就在在进程修改之前,在物理内存中出现开辟一个空间,开辟完成之后...修改的只是进程的物理地址和页表,而地址空间里面的依然是虚拟地址进程和进程的虚拟地址是一样的,只是映射到物理内存到不同区域,所以对应看到的地址是一样的,但内容却不一样。...当进程一旦创建进程,进程为了支持写时拷贝,因为进程走到已初始化全局区本来就是可以写的,但创建进程之后,操作系统直接修改页表中该位置的权限,都修改为r。

12810

【Linux】进程地址空间

/mytest ,执行mtest可执行程序 进程被全局数据的修改,被不影响进程 ,说明进程具有独立性,而进程是由内核数据结构+代码和数据组成的,独立性体现在数据上,所以通过写时拷贝的做法 使一个进程的变量被修改...,CPU自动根据页表将虚拟地址转化为物理地址 创建进程,就要创建进程的PCB,及地址空间和页表结构 进程的相关内核数据结构的属性字段继承进程 大富翁 A有个儿子是E,A跟E说,我们家有10...个亿是你爷爷的,所以E要继承给他10亿的大饼 所以进程在虚拟地址处也有对应的地址 正常来说,进程要对value对修改,把value变成200,进程通过映射关系找到value,读到200 但因为进程具有独立性...,进程对数据的修改,不影响进程 进程要对value修改时,在内存中重新申请一块空间,拷贝value值给新空间,重新映射指向新开辟的空间,导致不影响进程的value值 ,最终将新开辟的空间value...,在地址空间中申请空间,在页表处只填写虚拟地址,物理地址处不填写,就不需要在物理地址处申请空间,过一,进程尝试对空间写入,在重新申请空间把映射关系创建好,整体机制被叫做 缺页中断 8.

3K10

Linux进程地址空间

Linux进程地址空间是学习Linux的过程中,我们遇见的第一个难点,也是重中之重的重点。虽然它很难,但是,等我们真正懂得了这样设计的原理,我们不禁感叹:这真的是太妙了。...虽然每一个进程只有1个虚拟空间,但是这个虚拟空间可以被别的进程来同享。如:进程同享进程的地址空间,而mm_user和mm_count就对其计数。...有一进程在调用fork函数创建进程时,操作系统会将进程的PCB,mm_struct结构体,包括页表复制一份给进程,所以父子进程中相同的虚拟地址通过页表映射找到同一块内存空间,读取到相同的数据。...如果其中一个进程想要对数据进行修改,我们知道进程之间必须确保独立性,一个进程修改的数据极有可能影响到另一个进程。...其中,这种父子进程先共享一份内存数据,然后等到进程要对共享数据进行修改时,操作系统为了保证进程之间的独立性,才为其分配各种的内存空间,这种方式叫做写时拷贝。

6210

【Linux】进程地址空间

g_val 的值以后,进程和进程的 g_val 不同,这是正常的,因为我们在上一节进程概念中就说过,进程具有独立性,不同进程之间互不影响,包括父子进程;但是这里还发生了一个神奇的现象 – 进程和进程...此时,我们就能解释上面的现象了 – 进程和进程都拥有自己的单独的进程地址空间,且进程的地址空间是从父进程那里拷贝来的,所以最开始二者的 g_val 其实指向同一块物理内存; 现在进程想要修改自己地址空间中...所以虽然进程和进程 g_val 的虚拟地址相同,但是它们通过各自的页表映射到的物理地址是不相同的,自然也可以从物理内存中取出不同的数据。...对于互不相关的两个进程来说,它们都拥有自己独立的地址空间以及页表,页表映射到不同的物理内存上,磁盘代码和数据加载到内存中的位置也不同,一个进程数据的改变不会影响另一个进程; 对于父子进程来说,由于进程的...mm_struct 和 页表 是通过拷贝进程得到的,所以二者指向同一块物理内存,共用内存中的同一份代码和数据,但即使是这样,进程/进程在修改数据是也会发生写时拷贝,不会影响另一个进程,保证了进程的独立性

3.8K00

Linux系统-进程地址空间

进程以进程为模板构建进程,代码父子共享,数据各有一份(谁进行写入谁发生拷贝) 而我们发现进程数据发生修改时,进程数据的地址进程的地址一样,没有发生改变 对于变量内容不一样,但地址值是一样的...PCB找到对应的进程地址空间,再由进程地址空间上的虚拟地址由页表找到物理空间上分配的数据 示图: 对于父子进程变量地址相同数据不同: 进程创建进程时,进程以进程为模板构建进程,代码数据父子共享...,当进程进行修改数据时,由页表发现该数据是父子进程共享的,所以系统找到另一个物理空间进行拷贝数据,拷贝数据后再修改数据,达到数据各有一份互不干扰的目的 注:这种在需要进行数据修改时再进行拷贝的技术称为写时拷贝...示图: 3、相关问题 为什么数据要进行写时拷贝 进程需要保证独立性,多进程运行,需要独享各种资源,多进程运行期间互不干扰,数据写实拷贝让进程的修改不影响进程 为什么不在创建进程的时候就进行数据的拷贝...进程不一定会使用进程的所有数据,并且在进程不对数据进行写入的情况下,没有必要对数据进行拷贝,我们应该按需分配,在需要修改数据的时候再分配(延时分配),这样可以高效的使用内存空间 如果

3.8K30

返回栈空间地址 问题

当我们返回栈空间地址时会报错,为什么呢?那让我们先看一下什么是返回栈空间地址? 下面是错误示范: vs2022版演示  出现问题,不要慌,那我们就先调试一下。...3.进入GetMory函数,字符型的数组p 赋值为“hello”,return p;p是一个数组,return p;p是数组名,实际是返回的数组的首元素地址‘h’的地址。...当GetMory函数结束时,p就会自动销毁,也就是说p所开辟的空间就会还给操作系统,但p那块空间地址还存在而且传给了str,当str顺着这个地址访问时,地址原来的空间已经被销毁了,不存在了,但我还要去访问那块空间...答案是肯定哒,yes  上面就是栈空间地址问题的讲解,总结一下简单可以理解为,函数调用如果返回值为一个局部地址,就会出错,除非返回变量,或加上static修饰。...另外加一个知识点,如果空间是在堆区上开辟的,堆区只有  free来释放空间,所以不存在返回占栈空间地址问题。

10520

Linux进程——进程地址空间

本篇主要内容: 了解程序地址空间 理解进程地址空间 探究页表和虚拟地址空间 1....因为我们之前讲过进程按照进程为模版,父子并没有对变量进行进行任何修改 但是在达到一定条件之后,父子进程,输出地址是一致的,但是变量内容不一样! 但是相同的地址为什么会有不同的值?...每一个进程都要有地址空间,系统中,一定要对地址空间做管理!! 而操作系统管理地址空间,一定是“先描述,在组织”!地址空间最终一定是一个内核的数据结构对象, 就是一个内核结构体!...所以页表可以进行安全评估,有效的进行进程访问内存的安全检查 在除去上面提到的东西以外,页表还可以通过二进制衡量能存中有没有内容,是否分配地址 当我们有个虚拟地址要被访问了,但是它并没有被分配空间,更不会有内容...如果我们还想继续划分就会有多个struct vm_area_struct的结构,然后他们构成一个线性划分的链表结构。

11110

Linux之进程地址空间

i变量,进程和进程访问时获得的值却不是相同的,这是什么原因呢?...3.现象的具体解释 进程和进程都有自己独立的进程地址空间,也有独立的页表结构。进程由进程创建,因此进程的进程地址空间是拷贝进程的进程地址空间。...后来,进程修改了i的值,操作系统通过页表映射发现i的值是两个进程共享的,操作系统为了保持进程的独立性,当进程或者进程任何一方尝试对共享的数据做写入,操作系统就会在物理内存上重新开辟一块新的内存空间拷贝原来的数据...方便进程之间的数据代码的解耦,保证了进程的独立性; 一个进程对数据的修改不会对另一个进程造成影响,保证了进程的独立性。...三、怎么办 操作系统要为每一个进程分配地址空间,那么操作系统是否要管理这些地址空间呢?当然是要管理的。 那么,操作系统怎么管理进程的地址空间

19020

【Linux 内核 内存管理】虚拟地址空间布局架构 ① ( 虚拟地址空间布局架构 | 用户虚拟地址空间划分 )

文章目录 一、虚拟地址空间布局架构 二、用户虚拟地址空间划分 一、虚拟地址空间布局架构 ---- 在 64 位的 Linux 操作系统中 , " ARM64 架构 " 并 不支持 64 位的虚拟地址..., 最大只支持 48 位的虚拟地址 , 64 位地址太大 , 并不需要那么大的内存空间 ; " ARM64 架构 " 中 , Linux 系统的 " 内核虚拟地址 “ 与 ” 用户虚拟地址 "...是等同的 ; 用户虚拟地址 : 0x 0000 0000 0000 0000 ~ 0x 0000 FFFF FFFF FFFF , 48 位有效地址 ; 内核虚拟地址 : 0x FFFF 0000...0000 0000 ~ 0x FFFF FFFF FFFF FFFF , 48 位有效地址 ; 二、用户虚拟地址空间划分 ---- Linux 操作系统 进程 的 " 用户虚拟空间 " 起始地址...4.12\arch\arm64\include\asm\memory.h#86 中 , 定义了 TASK_SIZE 与 TASK_SIZE_64 宏 ; VA_BITS 是编译内核时 , 选择的 " 虚拟地址空间

7.1K20

静态链接-空间地址分配

这种做法非常浪费空间,因为每个段都会要求字节对齐要求,比如对于x86空间来说,段的装载地址空间的对齐单元为页,也就是4096字节。...那么就是说如果一个段的长度只有一个字节,它也要在内存中占用4096字节,这样造成空间内存的大量内部碎片。...“链接器为目标文件分配地址空间”这句话中的“地址空间”其实有两个含义: 在输出的可执行文件中的空间; 装载后的虚拟地址中的虚拟地址空间。...比如在“.text”和".data"来说,它们在文件中和虚拟地址都要分配空间,因为它们在这两者都存在;而在“.bss”这样的段来说,分配空间只局限与虚拟地址空间,因为它在文件中并没有内容。...在第一步的扫描和空间分配阶段,链接器按照前面介绍的空间分配方法进行分配,这时候输入文件中的各个段在链接后虚拟地址就已经确定,比如“.text”段起始地址为0x08048094,“.data”段的起始地址

1.9K60

进程的虚拟地址空间

在 Linux 系统中,每一个进程都在自己独立的地址空间中运行,在 32 位系统中,每个进程的逻辑地址空间均为 4GB,这 4GB 的内存空间按照 3:1 的比例进行分配,其中用户进程享有 3G 的空间...内存空间不足时,就需要将其它程序暂时拷贝到硬盘中,然后将新的程序装入内存。然而由于大量的数据装入装出,内存的使用效率就会非常低。 ⚫ 进程地址空间不隔离。...所有应用程序运行在自己的虚拟地址空间中,使得进程的虚拟地址空间和物理地址空间隔离开来,这样做带来了很多的优点: ⚫ 进程与进程、进程与内核相互隔离。...一个进程不能读取或修改另一个进程或内核的内存数据,这是因为每一个进程的虚拟地址空间映射到了不同的物理地址空间。提高了系统的安全性与稳定性。 ⚫ 在某些应用场合下,两个或者更多进程能够共享内存。...因为每个进程都有自己的映射表,可以让不同进程的虚拟地址空间映射到相同的物理地址空间中。通常,共享内存可用于实现进程间通信。 ⚫ 便于实现内存保护机制。

2.4K30

【Linux】对进程地址空间的理解

一、关于进程地址空间的简单理解 进程地址空间其实是分了很多个区域的,区域划分的本质就是区域内的各个地址都是可以使用的。...进程地址空间不是真实的物理内存,叫做虚拟内存。每一个进程都有自己独立的PCB,也有自己独立的地址空间。在32位机器下,进程地址空间的大小为[0,4GB]。...其中,PCB记录一个进程的起始地址或基地址,这其实就是进程地址空间的首地址。...上面图的地址空间和页表都是操作系统帮我们维护的。当进程创建进程的时候,操作系统会把上面的这些结构以及结构中的内容给进程爷拷贝一份。所以在进程刚创建出来时跟进程是访问同一块物理内存的。...当进程要对数据做修改时会发生写实拷贝,给进程要修改的数据重新开辟一块物理空间,再将重新开辟的这块物理空间地址填充入进程的页表中,但此时页表中对应的虚拟地址并没有发生变化,所以可以看到父子进程访问同一个虚拟地址却打印出不同的内容

9810

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

通过页表可以对非法的虚拟地址进行拦截,相当于变相的保护物理内存。 2:保证独立性 在谈第二点之前,有件事情需要我们处理——>解释1.2中的现象 那为什么相同地址进程和进程的数值不同呢?...global_val,于是global的内存中的地址就会通过页表映射到虚拟空间的某一个地址中,于是进程和进程就可以通过虚拟空间中的地址去访问global,并且打印时进程和进程对应的global对应的虚拟地址也是相同的...,因此开始时我们能看到进程和进程对应的global_val的数值和地址都相同。...当进程要改变global_val的值,由于进程与进程之间的独立性,一个进程改变变量不能影响另一个进程的同一个变量的改变,因此进程一旦要改变global_val,操作系统就会将进程页表与内存的物理地址之间的联系断开...这样子进程改变global_val的值也不会影响进程的global_val,这个操作与虚拟地址也没有任何关系。因此我们所看到的进程与进程的虚拟地址仍是相同的地址

1.1K00

内核地址空间大冒险:系统调用

2 神秘的长者 “欢迎来到内核地址空间!”,一位白胡子老头向我走了过来。 “敢问长者是谁”,我有点紧张。 ? “年轻人别怕,你是第一次来这里吧,难怪看着眼生。...“到后来,一些新出现的帝国文明,像咱们的Linux帝国,还有Windows帝国等等,为了安全考虑,一方面把普通应用程序和帝国自身程序分开,普通应用程序执行的地方叫用户态地址空间,而帝国核心程序运行的地方叫内核地址空间...还设立一个特殊通道,类似于虫洞,连接用户空间和内核空间。...“原来如此,那为何不直接把sys_open函数的地址写在我来之前的open房间,还要弄一个编号来查,这不更省事吗?” “唉,此言差矣,这些个函数的地址都是机密,怎么能随便透露给你们上面的应用程序呢。...而且,为了安全,这些地址随着帝国每次启动变化的,不是一个固定的地址,所以还是要用编号来查哦!” “感谢老先生,今日获益良多,时辰不早,我该去做我的正事了,再会”!

58910

Linux虚拟地址空间布局

这两块空间大小取决于栈、共享库的大小和数量。这样来看,是否应用程序可申请的最大堆空间只有2GB?事实上,这与Linux内核版本有关。...若程序员不释放,程序结束时操作系统可能自动回收。...操作系统为堆维护一个记录空闲内存地址的链表。当系统收到程序的内存分配申请时,遍历该链表寻找第一个空间大于所申请空间的堆结点,然后将该结点从空闲结点链表中删除,并将该结点空间分配给程序。...而频繁申请释放操作造成堆内存空间的不连续,从而造成大量碎片,使程序效率降低。...若操作对象是立即数(具体数值),将直接包含在代码中;若是局部数据,将在栈区分配空间,然后引用该数据地址;若位于BSS段和数据段,同样引用该数据地址。 代码段最容易受优化措施影响

3.3K40

DragonOS的MMIO地址空间自动分配

由于计算机上的很多设备都需要MMIO的地址空间,而每台计算机上所连接的各种设备的对MMIO地址空间的需求是不一样的。...如果我们为每个类型的设备都手动指定一个MMIO地址,会使得虚拟地址空间被大大浪费,也增加系统的复杂性。并且,我们在将来还需要为不同的虚拟内存区域做异常处理函数。...为驱动程序分配4K到1GB的MMIO虚拟地址空间 对于这些虚拟地址空间,添加到VMA中进行统一管理 可以批量释放这些地址空间 这套机制是如何实现的?...这套机制本质上是使用了伙伴系统来对MMIO虚拟地址空间进行维护。在mm/mm.h中指定了MMIO的地址空间范围,这个范围是0xffffa10000000000开始的1TB的空间。...MMIO虚拟地址空间的释放 当设备被卸载时,驱动程序可以调用mmio_release函数对指定的mmio地址空间进行释放。

81330
领券