[操作系统基础]程序运行时内存的分区以及作用
程序运行过程中,用来存放数据的内存可以分为如下几个模块:
1. 全局区(静态区):存放全局变量和静态变量,与其他变量的明显区别就是生命周期不同,程序结束时,系统自动释放这块资源。
2. 文字常量区:常量字符串存放在这个位置,也就是常量池。程序结束时,系统自动释放这块区域。
3. 栈区:存放函数的参数值,局部变量的值。他的生命周期较短,进入作用域的时候分配占用内存,离开作用域的时候释放占用的内存。
4. 堆区:一般是由人为控制这块区域的内存分配和释放。在C和C++中,堆内存如果忘记释放,可能导致可用内存越来越少,这就是内存泄漏。而在Java中,因为有了垃圾回收机制,这样的内存会被自动处理,所以在java中,不需要程序员自己主动释放内存。
堆和栈的区别:
1. 内存分配方面。堆是由程序员分配和释放,可用到的关键字有new,malloc,delete,free等。栈是由编译器自动分配和释放的。
2. 申请方式方面。堆是由程序员自己申请,而栈是程序自动分配。
3. 系统响应方面。堆:操作系统有一个记录空闲内存地址的链表,当系统收到程序的申请时,会遍历该链表,寻找第一个空间大于所申请空间的堆结点,然后将该结点从空闲结点链表中删除,并将该结点的空间分配给程序,另外,对于大多数系统,会在这块内存空间中的首地址处记录本次分配的大小,这样代码中的delete语句才能正确的释放本内存空间。另外由于找到的堆结点的大小不一定正好等于申请的大小,系统会自动的将多余的那部分重新放入空闲链表中。栈:只要栈的剩余空间大于所申请空间,系统将为程序提供内存,否则将报异常提示栈溢出。
4. 大小限制方面。堆:是向高地址扩展的数据结构,是不连续的内存区域。这是由于系统是用链表来存储的空闲内存地址的,自然是不连续的,而链表的遍历方向是由低地址向高地址。堆的大小受限于计算机系统中有效的虚拟内存。由此可见,堆获得的空间比较灵活,也比较大。 栈:在Windows下, 栈是向低地址扩展的数据结构,是一块连续的内存的区域。这句话的意思是栈顶的地址和栈的最大容量是系统预先规定好的,在WINDOWS下,栈的大小是固定的(是一个编译时就确定的常数),如果申请的空间超过栈的剩余空间时,将提示overflow。因此,能从栈获得的空间较小。
5. 效率方面。栈的速度比堆要快,但是程序员无法控制栈的分配。