一、程序占用内存分配 程序占用的内存分为 栈区、堆区、全局区(静态区)、文字常量区、程序代码区。 重点以下两个: 1、栈区(stack) 此区域由编译器自动释放。 2、堆区(heap) 一般由程序员手动释放。若是没有释放,程序结束时可能由OS操作系统回收。
栈(Stack):局部变量,函数参数等存储在该区,由编译器自动分配和释放.栈属于计算机系统的数据结构,进栈出栈有相应的计算机指令支持,而且分配专门的寄存器存储栈的地址,效率分高,内存空间是连续的,但栈的内存空间有限。 堆(Heap):需要程序员手动分配和释放(new,delete),属于动态分配方式。内存空间几乎没有限制,内存空间不连续,因此会产生内存碎片。操作系统有一个记录空间内存的链表,当收到内存申请时遍历链表,找到第一个空间大于申请空间的堆节点,将该节点分配给程序,并将该节点从链表中删除。一般,系统会在该内存空间的首地址处记录本次分配的内存大小,用于delete释放该内存空间。 全局/静态存储区:全局变量,静态变量分配到该区,到程序结束时自动释放,包括DATA段(全局初始化区)与BBS段(全局未初始化段)。其中,初始化的全局变量和静态变量存放在DATA段,未初始化的全局变量和静态变量存放在BBS段。BBS段特点:在程序执行前BBS段自动清零,所以未初始化的全局变量和静态变量在程序执行前已经成为0. 文字常量区:存放常量,而且不允许修改。程序结束后由系统释放。 程序代码区:存放程序的二进制代码。
//main.cpp
int a = 0; //全局初始化区
int a = 0; //全局初始化区
char *p1; //全局未初始化区
main() {
? ? int b; //栈
? ? char s[] = "abc"; //栈
? ? char *p2; //栈
? ? char *p3 = "123456"; //123456\0在常量区,p3在栈上。
? ? static int c = 0; //全局(静态)初始化区
? ? p1 = (char *)malloc(10);
? ? p2 = (char *)malloc(20);
? ? //分配得来得10和20字节的区域就在堆区。
? ? strcpy(p1, "123456");?
? ? //123456\0放在常量区,编译器可能会将它与p3所指向的"123456"优化成一个地方。
}
二、其他 栈和堆的区别 1.栈在执行期间编译器自动分配,编译器用它实现函数调用,调用函数时,栈增长,函数返回时栈收缩。 而堆是程序员手动分配和释放,申请内存用malloc释放用free。 2.栈是高地址向低地址增长;堆是低地址向高地址增长。 3.栈有栈溢出。堆有堆溢出。
什么是内存泄漏?怎么产生的? 简单说,申请了一块空间,使用完毕后没有释放。它的一般表现形式是程序运行时间越长,占用内存空间越多,最终用尽全部内存,整个系统崩溃。 由程序申请的一块内存,且没有任何一个指针指向它,那么这一块内存就泄露了。 内存管理 以Linux 32位平台为例,进程有4GB大小的虚拟地址空间,其中1GB留给系统内核,3GB是进程自身拥有。一个进程大致的内存布局如下图所示。
?
?
?
三、总结 堆和栈的差别 主要的区别由以下几点:
1、管理方式不同;
2、空间大小不同;
3、能否产生碎片不同;
4、生长方向不同;
5、分配方式不同;
6、分配效率不同;
|