c++:4G虚拟地址空间布局

4G的虚拟内存空间:

其中1G是属于内核空间,另外的3G属于用户空间

所有的进程都拥有属于自己的用户空间,但却共享一个内核空间

 

 3G用户空间:

1、保留区

保留区128M,我们通常将申请的临时指针变量初始化时置为NULL,可以防止后续无意使用这个指针出错,因为NULL == 0x0,将其指针指向0x0这个地址时,因为0x0这个地址属于保留区,没有访问权限的。

备注:保留区地址段内,在红帽子系统测试中C库在此区域,有数据段和代码段,

测试方法:cat  proc/pid/maps

2、.text段

指令段:通常是指用来存放程序执行代码的一块内存区域。这部分区域的大小在程序运行前就已经确定,并且内存区域通常属于只读, 某些架构也允许代码段为可写,即允许修改程序。在代码段中,也有可能包含一些只读的常数变量,例如字符串常量等

3、.data段

数据段(data segment)通常是指用来存放程序中已始化且不为0的全局变量和静态变量的一块内存区域。数据段属于静态内存分配。常量也放在这个区域。

4、.bss段

数据段:(Bss Segment)通常是指用来存放程序中未初始化或者初始化为0的全局变量的一块内存区域,在程序载入时由内核清0。bss段属于静态内存分配。

PS:.data段与.bss段的区别(为什么有两个数据段)
     1) BSS段不占用物理文件尺寸,但占用内存空间;数据段占用物理文件,也占用内存空间。所以有两个数据段节省文件空间。
     对于大型数组如int ar0[10000] = {1, 2, 3, ...}和int ar1[10000],ar1放在BSS段,只记录共有10000*4个字节需要初始化为0,而不是像ar0那样记录每个数据1、2、3...,此时BSS为目标文件所节省的磁盘空间相当可观。
     2) 当程序读取数据段的数据时,系统会出发缺页故障,从而分配相应的物理内存;当程序读取BSS段的数据时,内核会将其转到一个全零页面,不会发生缺页故障,也不会为其分配相应的物理内存。

5、heap

 堆:一般由程序员分配释放, 若程序员不释放,程序结束时可能由OS回收,堆区域执行了malloc才存在

保存函数内部动态分配内存,是另外一种用来保存程序信息的数据结构,更准确的说是保存程序的动态变量。堆是“先进先出”数据结构。它只允许在堆的一端插入数据,在另一端移走数据。堆的地址空间“向上增加”,即当堆上保存的数据越多,堆的地址就越高。

6、共享库

在编写程序时,会依靠其他人已经写好的许多代码来执行例程或特殊功能。 这些代码存储在共享库中使用它们,需要将它们与自己的代码相链接,无论是在构建程序时还是在运行程序时。

7、stack

栈,由编译器自动分配释放,行为类似数据结构中的栈(先进后出)。
     栈主要有三个用途:
     ①函数的返回地址(以便从被调用者返回)和参数
     ②存放临时变量:包括函数的非静态局部变量以及编译器自动生成的其他临时变量
     ③保存上下文:包括在函数调用前后需要保持不变的寄存器

8、命令行参数

int main()//这是我们平常写的main函数

{

}

int main(int argc, char *argv[],char *envp[])//这是真实的main函数

{

}

int argc表示命令行参数的个数(包括可执行程序名本身),char *argv[]表示每个参数的具体内容,argv[0]为命令行中可执行程序名本身,argv[1]为命令行中第二个参数的内容,

9、环境变量

例:int execve(char *pathname,char* argv[],char*envp[])  ,char*envp就是所谓的环境变量

在我们调用一些系统库函数的时候,我们需要使用预处理指令#include。但是我们系统怎么知道去哪个路径寻找这些头文件的函数定义呢?就是通过char *envp[](环境变量)来实现的。

 

 

1G内核空间:

作用:Linux 操作系统和驱动程序运行在内核空间

物理地址 = 逻辑地址 – 0xC0000000:这是内核地址空间的地址转换关系,注意内核的虚拟地址在“高端”,但是ta映射的物理内存地址在低端。

①:内存直接访问(ZONE_DMA(大约16MB))

全名ZONE_DirectMemoryAccess(直接内存访问),可以加快磁盘和内存之间数据的交换,不需要经过CPU的寄存器,这时CPU可以去干别的事,大大增加了效率。

②:常用区域(ZONE_NORMAL)

内核中最重要最常用的部分。用于直接映射。PCB就在这里。

③:ZONE_HIGHMEM (128MB)

所谓的高端内存,用于在内核中映射高于1G的物理内存时使用。64位系统则没有该段(根本不需要,因为64位操作系统给内核空间分配的内存达到512G)。

内存分配方式:

(1) 从静态存储区域分配 。内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在。例如全局变量、static 变量 。

(2) 在栈区分配:相关代码执行时创建,执行结束时被自动释放。局部变量在此存储。栈内存分配运算内置于处理器的指令集中,效率高,但容量有限。

(3)在堆区分配:动态分配内存。用new/malloc时开辟,delete/free时释放。生存期由用户指定,灵活。但有内存泄露等问题。

内存泄漏情况详情见:https://mp.csdn.net/postedit/97110709

参考博客:https://blog.csdn.net/FoXiShaoNv/article/details/84261197 

 

 

 

 

 



 

 

 

 

 

  • 2
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值