Windows内存技术

Windows内存技术

WIN32中,每个应用程序都可看见”4GB的线性地址空间, 其中最开始的4MB和最后的2GB由操作系统保留,低的2GB为进程的私有空间(如果在Boot.ini文件中使用“/3GB”的开关可以使进程的私有空间增大到3GB,系统空间1GB)。

对于每个进程来讲其虚拟的地址空间是连续的,实际上它们是以页面为单位离散的存在于物理内存中,一些可能被交换到硬盘上的页面文件中,而且还有大部分的空间是未提交(Uncommitted)的。

进程的地址空间是如何划分的

 

x86 32

Windows

3 GB用户模式下的x86 32

Windows

x64 64 Windows

IA-64 64 Windows

空指针
赋值
分区

0x00000000

0x0000FFFF

0x00000000

0x0000FFFF

0x00000000’00000000

0x00000000’0000FFFF

0x00000000’00000000

0x00000000’0000FFFF

用户模
式分区

0x00010000

0x7FFEFFFF

0x00010000

0xBFFEFFFF

0x00000000’00010000

0x000007FF’FFFEFFFF

0x00000000’00010000

0x000006FB’FFFEFFFF

64 KB禁入分区

0x7FFF0000

0x7FFFFFFF

0xBFFF0000

0xBFFFFFFF

0x000007FF’FFFF0000

0x000007FF’FFFFFFFF

0x000006FB’FFFF0000

0x000006FB’FFFFFFFF

内核模
式分区

0x80000000

0xFFFFFFFF

0xC0000000

0xFFFFFFFF

0x00000800’00000000

0xFFFFFFFF’FFFFFFFF

0x000006FC’00000000

0xFFFFFFFF’FFFFFFFF

 

CPU体系结构、对应的用户模式可用地址区间以及分区的大小

CPU体系结构

用户模式分区的可用地址区间

用户模式分区的大小

x86(普通)

0x00010000 → 0x7FFEFFFF

~2 GB

x86w/3GB

0x00010000 → 0xBFFEFFFF

~3 GB

x64

0x00000000’00010000 → 0x000007FF’FFFEFFFF

~8192 GB

IA-64

0x00000000’00010000 → 0x000006FB’FFFEFFFF

~7152 GB

 

C++程序是由一下几部分组成:

(1) 正文段 (.text)

程序代码就存储在.text 段,这是由CPU执行的机器指令部分。通常,正文段是可共享的,所以即使是经常执行的程序(如文本编辑程序、C编译程序、shell)在存储器中也只需有一个副本,另外,正文段常常是只读的,以防止程序由于意外事故而修改其自身的指令。

当你在链接定位文件中将该符号放置在代码段后,那么该符号表示的值就是代码段大小,编译连接时,该符号所代表的值会自动代入到源程序中。

(2) 只读数据段 .rdata

只读数据是在程序运行期间不能被修改的,程序只能读取这些数据,因此编译器把他们组织在一起存储在只读数据段。

(3) 初始化数据段.data

data端用于存储经过初始化的数据,包括带初值的全局变量和static变量,都存储在data区。data段的起始位置也是由连接定位文件所确定,大小在编译连接时自动分配,和程序大小没有关系,但和程序使用到的全局变量,常量数量相关。

(3) 未初始化数据段.bss

bss这一名称来源于早期汇编程序的一个操作符意思是Block Started by Symbol(由符号开始的块),通常是指用来存放程序中未初始化的全局变量的一块内存区域,在程序载入时由内核清0 BSS段属于静态内存分配。它的初始值也是由用户自己定义的连接定位文件所确定,用户应该将它定义在可读写的RAM区内,源程序中使用malloc分配的内存并不是这一块,它不是根据data大小确定,主要由程序中同时分配内存最大值所确定,不过如果超出了范围,也就是分配失败,可以等空间释放之后再分配。

(4) stack

stack是用来存储局部变量以及每次函数调用时所需保存的信息。每次函数调用时,其返回地址、以及调用者的环境信息(例如某些机器寄存器)都存放在栈中。然后,新被调用的函数在栈上为其自动和临时变量分配存储空间。通过以这种方式使用栈, C函数可以递归调用。stack是一种后进先出Last In First OutLIFO)的数据结构,这意味着最后放到栈上的数据,将会是第一个从栈上移走的数据。对于哪些暂时存贮的信息,和不需要长时间保存的信息来说,LIFO这种数据结构非常理想。在调用函数或过程后,系统通常会清除栈上保存的局部变量、函数调用信息及其它的信息。栈另外一个重要的特征是,它的地址空间向下减少,即当栈上保存的数据越多,栈的地址就越低。栈(stack)的顶部在可读写的RAM区的最后。

(5) heap

编译器通常在堆中进行动态内存分配。

由于历史上形成的惯例,堆位于非初始化数据段顶和栈底之间。堆是先进先出First In first OutFIFO)数据结构。它只允许在堆的一端插入数据,在另一端移走数据。堆的地址空间向上增加,即当堆上保存的数据越多,堆的地址就越高。

?????图片????

?????图片????

?????图片????

?????图片????

?????图片????

?????图片????

?????图片????

数据存储

(1) 常量

对于整型常量和字符型常量,由于不需要写操作,编译器会将其直接编译在代码之中,因此不需要存储。正文段 (.text)代码段

对于字符串常量,编译器将其放入只读数据端.rdata,同事对于相同的字符串常量,编译器会优化并只存储一次。只读数据段(.rdata) 数据段

(2) 变量

- 全局变量

未初始化的,存储于.bss 未初始化数据段(.bss) 数据段

初始化的,存储于.data ; 初始化数据段(.data) 数据段

- 静态变量

未初始化的,存储于.bss 未初始化数据段(.bss) 数据段

初始化的,存储于.data ; 初始化数据段(.data) 数据段

-自动变量

局部变量存储于stack

动态分配的内存,存储于heap

- 寄存器变量

存储位置在CPU寄存器内。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值