首页 > 系统相关 >【操作系统】进程的内存映像

【操作系统】进程的内存映像

时间:2024-09-12 23:23:37浏览次数:14  
标签:存储 操作系统 映像 这片 地址 区域 内存 当中 变量

进程的内存映像,也就是说一个进程在运行的时候它在内存里边是什么样子,为了方便大家理解我们结合这个C语言程序来解释,                                                                                                           

假设这个计算机系统是三十二位的,也就意味着每个进程拥有4gb 的虚拟地址空间,那地址的范围就应该是从0000 0000一直到ffff ffff .那可以看到在这个示意图当中最上面高地址的这1gb 会用于存储操作系统的一些内核数据比如说进程的 PCB,再比如说进程的页表,另外操作系统的代码也是存储在高地址的这1 gb 当中,比如进程调度就属于内核代码,这些代码就是存储在这片区域。

这是高地址的1 gb,那我们作为普通程序员我们写的这个程序它只能访问用户区的这片数据而不能直接访问操作系统内核区的这些数据。

接下来我们来研究一下用户区里边存储了哪些数据,首先在低地址的 这个部分会有一片我们不会使用的区域,地址范围就是从0000 0000一直到0804 8000这个地址,然后从这个地址到 c000 0000这一整片的区域就会被我们的用户进程所使用,我们从低地址往高地址来看。地址最低的这片区域会用于存储只读代码以及只读数据,我们知道我们写的这些代码在正式运行之前会经过编译链接等等一系列的处理把这些代码翻译为与之等价的机器指令, 那这些机器指令在程序运行过程当中是不会改变的,所以它属于只读代码。在程序运行过程当中只能读这些 机器指令而不能写这些机器指令。因此我们在 c 语言里面写的这些程序代码最终会被翻译为机器指令然后在程序运行的时候是被存储在紫色的这片区域当中,那除了这些指令代码之外还有一些只读的数据也是存储在这片区域,在 c 语言当中有这样的一个关键字叫做 const, 用const 关键字去修饰一个变量那么这个变量就是常变量,这种变量的值在程序运行过程当中是不可以改变的。也就说对于这类的变量只能读它的数据而不能写它的数据,所以但凡 const 关键字修饰的这些变量都会被存储在紫色的这一片区域当中。

在这片区域之上会有一片区域用于存储可以读也可以写的那些数据,结合 c 语言程序来说就是我们熟悉的全局变量和静态变量。那在这个程序当中,a 这个变量是被定义在 main 函数之外它属于全局变量所以 a 存储在绿色这片区域,另外在main 函数里边这儿有个变量 c 它用 static 的关键字修饰属于静态变量,所以 c 这个变量它是被存储在绿色这片区域的,那这片区域的数据就是既可以读也可以写,

刚才提到的这两片数据区域在程序运行的时候或者说进程启动的时候就可以确定这两片区域的大小是多少,并且在整个进程运行的过程当中,它们的大小是固定不变的。这也很好理解,因为一个程序它的代码一旦写完之后这个程序对应的指令它的大小是多少就确定了。另外整个程序当中它到底定义了多少个常变量,在程序启动的时候 也可以确定。 另一方面我们写的代码当中总共定义了多少个全局变量总共定义了多少个静态变量,这些在进程启动的时候就可以确定的,并且在整个程序运行的过程当中这些数据的大小是不会改变的。                                                                               

继续往上看在读写数据这片区域上面就会有一片区域称为堆,英文是 heap ,                                   

那结合 c 语言来看,在 c 语言当中但凡用 malloc 和 free 这两个函数去处理的那些数据就是存储在堆这片区域当中,显然堆这一片数据区域它的大小肯定是可以动态的增加或者减少的。

对于三十二位的系统来说,堆区最多只能到4000 0000这个地址,也就是说堆加上刚刚提到的这三片区域总共只有1 gb 的大小,六十四位的系统它 可以 malloc 的空间还会更大,这就不展开细聊了。

回到上面这个例子,整个地址空间总共有4 gb 操作系统用掉了1 gb 然后低地址的这些部分用掉了1gb,现在中间还剩下2 gb 的部分。那这2gb 的低地址部分是共享库的存储映射区,结合我们熟悉的 c 语言来看,我们在 c 语言当中经常会调用一些系统提供的库函数,

那这些库函数的指令代码就会存储在黄色的这片区域当中,比如说这个地方使用到的print 函数,它的指定代码就是存储在共享库的存储映射区,显然不同的程序它有可能使用到的库函数数量是不一样的。你使用的库函数越多,那么这片区域肯定也会越大越往上增长。

那这是黄色的这片区域,接下来再往上看从中间的这两 gb 高地址的部分这个部分会有一片区域用来存储用户栈

我们知道程序运行的时候就是从 main 函数开始 ,main函数可能会调用其他的函数。那每调用一层函数,就需要保存上一层函数的信息同时也需要开辟一 片新的空间去存储被调用函数的相关信息,那所有的和函数调用相关的数据就存储在用户栈这片区域当中,显然这片区域也是会动态的增加或者减少的,你调用的函数层数越多,那么这个用户栈肯定也会越往下面这个方向去增长,那我们在每一个函数里边定义的局部变量以及函数调用的一些调用参数等等这些东西就是存储在用户栈里面,这就是进程的内存映像。

最后我们还需要解释一个东西,我们在 c 语言当中经常会用这种宏定义的方式定义一些常量,很多同学可能会误以为既然它是常量所以它应该被存储在紫色的这片区域当中。比如说 X 的值等于 1024,那么有没有可能在紫色的这片区域当中分配出四个字节用于存储 x 这个常量呢。

事实上这种理解是不对的,我们宏定义的常量不会在内存当中专门的分配存储的空间,那在预编译的阶段你的编译器会把这个X 把它自动的替换为1024,替换之后这个值会被隐含到程序指令当中,这个学过计算机组成原理的同学应该能够理解。在计组当中有一种寻址方式叫做立即数,也就是说程序指令当中就直接包含了1024,而如果没学过计组的同学可以不用深究。总之这儿想强调的就是宏定义的常量它并不会存储到紫色这片区域当中,用 const 关键字定义的这种常变量它会被存储到紫色这片区域当中。大家只需要记住这个结论就可以。

这就是进程的内存映像。

标签:存储,操作系统,映像,这片,地址,区域,内存,当中,变量
From: https://blog.csdn.net/qq_56249308/article/details/142067727

相关文章

  • 操作系统实验——存储器的分配与回收算法实现
    1.实验内容:Exercise1:本实验是模拟操作系统的主存分配,运用可变分区的存储管理算法设计主存分配和回收程序,并不实际启动装入作业。Exercise2:采用最先适应法、最佳适应法、最坏适应法分配主存空间。Exercise3:当一个新作业要求装入主存时,必须查空闲区表,从中找出一个......
  • VisualStudio 2022 找不到内存 反汇编 寄存器调试工具
    本文将告诉大家如何解决在VisualStudio2022的调试-窗口里面找不到内存、反汇编、寄存器这三个调试工具的问题找不到的原因是没有启用地址级调试只需要在“工具”(或“调试”)>“选项”>“调试”中选择“启用地址级调试”然后进行调试即可看到开启之后,即可在调试-窗口......
  • [操作系统]用户态内核态
    用户态内核态用户态线程和内核态线程有什么区别?这是一个组合型的问题,由很多小问题组装而成,比如:用户态和内核态是什么?用户级线程和内核级线程是一个怎样的对应关系?内核响应系统调用是一个怎样的过程?什么是用户态和内核态Kernel运行在超级权限模式(SupervisorMode)下,所以拥......
  • 【C语言】浮点数在内存中的存储
    引言之前我们已经学习过 整数在内存中的存储,现在我们来学习浮点数在内存中的存储【整数存储】 ......
  • 本地内存和分布式缓存(面试)
    本地缓存和分布式缓存本地缓存:缓存组件和应用在同一进程中。但各应用都需要维护单独的缓存,无法共享缓存。分布式缓存:缓存组件和应用分离,不在同一进程,多个应用可直接共享缓存。本地缓存的实现缓存一般是一种key-value的键值对数据结构与此同时,本地缓存由于需要被并发读写......
  • 【读书笔记-《30天自制操作系统》-18】Day19
    本篇内容涉及到文件与文件系统,以及应用程序的运行。首先实现type命令,读取文件并显示;接下来导入对FAT文件系统的支持,实现读取大小512字节以上,存放在不连续扇区中的文件。在此基础上,最终实现读取并运行应用程序。1.type命令实现type命令是Windows命令行中用于读取并显示文......
  • c语言--整数和浮点数在内存中的存储
    一整数在内存中的存储1.1源码反码补码整数的2进制表⽰⽅法有三种,即原码、反码和补码。有符号的整数,三种表⽰⽅法均有符号位和数值位两部分,符号位都是⽤0表⽰“正”,⽤1表⽰“负”,最⾼位的⼀位是被当做符号位,剩余的都是数值位。正整数的原、反、补码都相同。负整数的三种......
  • C 语言内存管理语法全解析(malloc、calloc、free)
    目录一、引言二、动态内存分配1.malloc函数2.calloc函数 3.realloc函数 三、内存释放 1.free函数 2.内存泄漏的避免四、内存管理的最佳实践1.检查内存分配的返回值2.避免内存访问越界  3.释放内存的顺序4.使用内存管理工具五、总结 一、引言   ......
  • C语言进阶【3】---C语言内存函数
    本章概述本章函数概述memcpy使用和模拟memmove使用和模拟memset函数的使用memcmp函数的使用彩蛋时刻!!!本章函数概述我们在本章的博客中讲的内容是有关内存的操作,我们直接通过内存块对数据进行操作。因为我们是直接对内存块操作,所以可以对任意类型数据进行操作(我们没......
  • 【项目实战】NIO 与 直接内存 (Direct Memory),由JVM直接管理,而不是通过垃圾回收器来管
    一、技术概览1.1定义直接内存,DirectMemory。直接内存,是指位于Java堆外的一块内存区域。直接内存,由JVM直接管理,而不是通过垃圾回收器来管理。直接内存,可以通过Java的ByteBuffer.allocateDirect()方法创建。直接内存,可以提高数据传输效率,特别是当数据需要频繁地在网络......