进程内存布局

从上图可以看出,进程内存地址空间被划分为8块(Managed Heap是另一种内存堆),并且各块内存不是聚集在一起形成连续内存块,而是按需加载使用内存;他们的详细情况如下:

内存块英文名

中文名

详细说明

Image

映像内存

EXE、DLL等加载到这里

Mapped File

内存映射文件

共享内存,用于进程间通讯

Shareable

可共享内存

 

Heap

(Managed Heap)

内存堆

堆内存,new/new[]/malloc等都在堆空间分配,默认为1 MB;Managed Heap 供CLR使用的堆

Stack

堆栈

 

栈内存,用做函数参数、局部变量的存储空间,默认为1 MB

Private Data

私有数据

 

Page Table

内存页表

内存分配页表

Free

自由内存

可用的内存空间

 

由于编译器在后台做了大量的内存管理自动化工作,因此程序设计过程中主要关注的内存区域类型有:Stack、Heap、Free(Free Virtual Address Space),下面我们对这几种做一个简要介绍:

 

Stack 是一块固定大小的连续内存,受运行时管理,无需用户自行分配和回收;当函数调用嵌套层次非常深时会产生 Stack overflow(堆栈溢出)错误,如递归调用、循环调用、消息循环、大对象参数、大对象局部变量等都容易触发堆栈溢出;

 

Heap 主要用于管理小内存块,是一个内存管理单元,默认为1MB,可动态增长;每一个应用程序默认有一个 Heap,用户也可以创建自己的 Heap,new/delete, malloc/free 都是从堆中直接分配内存块;

 

 

Free(Free Virtual Address Space)即进程空间中的整个可用地址空间,它会以两种方式被使用,一种是Heap 自动分配和回收,一种是直接使用VirtualAlloc*/VirtualFree* 分配和回收;用户对它的直接使用是用于分配连续大块内存,分配和释放的速度比使用 Heap 更快;

 

3.3、数据结构视图

内存始终都还是内存,所不同的是我们解读内存的方式不同;从代码视野来看内存中的数据结构,它就是对一块连续内存的专有解读;对任何一个内存地址,我们可以用数据结构A视图来解读,亦可以用数据结构B视图来解读,使用正确的数据结构视图读到正确的数据,使用错误的数据结构视图我们读到错误的数据;为了简明扼要的说明这个问题,我们来个案例:

由于操作系统已经接管了物理内存的使用,并且提供了透明的访问机制,对内存的使用更直接体现为对操作系统提供的进程地址空间的分配和回收;

 


 

在实际的编程实践中,程序员需要把整块空间再细分为8位、16位、32位、64位、8位连续块等数据空间,这里还涉及到两个概念:字节对齐和字节序列(又名端序,有大端小端之说),透彻理解编译器的对齐规则和处理所支持的字节序列,对于正确理解内存中的数据很关键。

posted @ 2017-06-07 20:30  xiaozhisir  阅读(907)  评论(0)    收藏  举报