4G虚拟地址空间布局如下图所示:
一、其中,用户进程部分分段存储内容如下表所示(按地址递增顺序)
名称 | 存储内容 |
代码段(.text) | 可执行代码、字符串字面值、只读变量 |
数据段(.data) | 已初始化且初始值为非0的全局变量和静态局部变量 |
BSS段 | 未初始化或初始值为0的全局变量和静态局部变量 |
栈 | 局部变量、函数参数、返回地址等 |
堆 | 动态分配的内存 |
在将应用程序加载到内存空间执行时,操作系统负责代码段、数据段和BSS段的加载,并在内存中为这些分配空间。栈也由操作系统分配和管理,堆区是动态内存的分配。
栈与堆的区别:
- 管理方式:对于栈来讲,是由编译器自动管理,无需我们手工控制;对于堆来说,释放工作由程序员控制,容易产生内存泄露。空间大小:一般来讲在32位系统下,堆内存可以达到3G的空间(4G有1G要给内核);而栈的最大容量是事先规定好的(例如,在VC6下面,默认的栈空间大小是1M,可修改)
- 碎片问题:对于堆来讲,频繁的new/delete势必会造成内存空间的不连续,从而造成大量的碎片,使程序效率降低;对于栈来讲,则不会存在碎片,因为栈是先进后出的结构,一个内存块要从栈中弹出,在它上面的后进的内存块肯定要先被弹出
- 生长方向:对于堆来讲,生长方向是向上的,也就是向着内存地址增加的方向;对于栈来讲,它的生长方向是向下的,是向着内存地址减小的方向增长;
- 分配方式:堆都是动态分配的;而栈有2种分配方式:静态分配和动态分配,静态分配是编译器完成的,比如局部变量的分配,动态分配由alloca函数(类似于malloc,专门在栈中申请空间的函数)进行分配,但是即使是动态分配,它也和堆是不同,栈的动态分配是由编译器进行释放,无需我们手工释放。
- 分配效率:栈是机器系统提供的数据结构,计算机会在底层对栈提供支持:分配专门的寄存器存放栈的地址,压栈出栈都有专门的指令执行,这就决定了栈的效率比较高;堆则是C/C++函数库提供的,它的机制是很复杂,例如:为了分配一块内存,库函数会在堆内存中搜索连续的足够大小的空间,如果没有足够大的空间(可能是由于内存碎片太多),就需要操作系统重新整理内存空间,这样就有机会分到足够大的内存,然后进行返回。显然,堆的效率比栈要低更多。
二、1G内核空间是大体分为三部分,部分存储内容如下表所示:
直接内存访问 | 不走寄存器直接在此访问 |
常用部分 | 做页目录表 |
高端内存 | 大文件的映射 |