小菜最近在笔试的时候老碰到内存分布的题型,今天详细的查阅了相关资料,对内存分布、堆和栈进行总结(以C语言为例)。
C程序的内存分布主要分为五个段:
1.代码段(text segment):用于存放机器指令,该部分可以被多个程序共享,而且为了避免代码被修改,该段位只读;
2.初始化数据段/数据段:程序中明确被初始化的变量,进入main函数之前的。通常为全局变量和static变量中初始化后的变量,文字常量等。
3.未初始化数据段/bss段:程序中为被初始化的变量,为初始化的全局变量、static变量
4.堆段(Heap):用于动态内存的分配,一般该部分有程序员在程序中调用malloc等申请内存的函数而分配,内存区使用完后需要进行内存释放,使用free函数。
5.栈段(Stack):内存自动分配。程序在执行系统自动分配内存,对应程序中的局部变量。Where automatic variables are stored, along with information that is asved each time a function is called(C实现递归的原理)。
各段在内存中的分布如下所示:
Stack + + |
+ + + Heap |
Bss |
Initialed Data |
Code |
前面介绍了堆和栈,内存中它们到底有什么不同呢?
堆和栈的不同点主要有以下几个方面:
1.管理方式:栈由操作体统进行管理,堆由程序员控制;
2.内存大小不同:一般32位系统中堆内存可以达到4G空间;对于栈来说,都是有一定的空间大小,VC6下面为1M;
3.内存增长方向不同:栈内存与栈数据结构类似,采用向下增长的方式,栈底为高地址;堆则地址增长方向为低地址向上增长;
4.分配方式不同:堆是动态分配;栈可以使用2中分配方式:静态分配和动态分配。静态分配是编译器完成,动态分配使用malloc,栈的动态分配由编译器释放。
5.分配效率不同:栈是一块比较连续的空间,是系统提供的数据结构,并有专用的指令进行push、pop操作,效率较高;而动态分配函数malloc在分配时,通过链表查询空闲的内存,内存块大于需要的内存大小时分配则分配内存,并将剩余的内存继续添加到空闲链表中;
6.是否产生内存碎片:在分配效率中谈到了具体的内存分配,栈内存是连续的,不易产生碎片;分配后剩余的内存有可能由于空余的内存过小而不可能再分配给其他程序使用,从而产生碎片。