分类:
2012-11-12 15:19:54
原文地址:程序运行中的内存分配 作者:11wping
内存分区
1)栈区(stack)- 由编译器自动分配释放,存放函数的参数值,局部变量的值等。其操作方式类似于数据结构中的栈。
2)堆区(heap) - 用于动态分配的存储,通过malloc函数获得的内存。一般由程序员分配释放,若程序员不释放,程序结束时可能由回收 .
3)全局区(静态区)(static)-,和静态变量的是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和未初始化的静态变量在相邻的另一块区域。 -程序结束后有系统释放。注意:全局区又可分为未初始化全局区:.bss段和初始化全局区:data段。
4)常量区-常量字符串就是放在这里的。程序结束后由系统释放
5)代码区-存放函数体的二进制代码即文本段。
C语言内存分配函数
1)malloc:
函数原型: void * malloc(unsigned size); 分配size字节大小的存储区,返回所分配的内存地址的起始地址。如内存不够,返回0;
malloc分配的字节数可能比指定的字节要多,这是由内存对齐方式决定的,malloc实际上调用了HeapAlloc函数, 因此malloc分配的内存也不能跨进程调用。
2)calloc:
函数原型: void * calloc(unsigned n,unsign size); 分配n个数据项的内存连续空间,每个数据项的大小为size,返回所分配的内存地址的起始地址。如内存不够,返回0;
分配指定数目的元素,每个元素的大小由size指定, 并将其初始化为0,calloc调用malloc使用C++ _set_new_mode函数来设置新的处理方式,默认情况下,malloc 失败时不调用分配内存的处理程序例程。
3)realloc:
函数原型: void * realloc(void *p,unsigned size); 将p所指向的已分配内存区的大小改为size,size可比原来空间大或小,返回所分配的内存地址的起始地址。
重新分配内存并返回void类型,如果没有足够的内存扩展内存块,则原来的指向的内存指针无变化,并返回NULL;如果重新分配大小设为0,而释放原来的内存块, 并返回NULL.
4)alloca
是在栈(stack)上申请空间,用完马上就释放。
在调用 alloca的函数返回的时候, 它分配的内存会自动释放。也就是说, 用 alloca 分配的内存在栈上。所以释放不需要用户使用free.
alloca不具可移植性,而且在没有传统堆栈的机器上很难实现。当它的返回值直接传入另一个函数时会带来问题,因为他分配在栈上。
5)new:
分配内存的对象或数组类型的对象和返回一个适当类型,并调用对象的构造函数及在delete时调用对象的析构函数。其实现基于malloc调用。
程序运行时,特别要注意的是内存的分配。有六个地方都可以保存数据:
寄存器 这是最快的保存区域,因为它位于和其他所有保存方式不同的地方:处理器内部。然而,寄存器的数量十分有限,所以寄存器是根据需要由分配。我们对此没有直接的控制权,也不可能在自己的程序里找到寄存器存在的任何踪迹。 堆栈 驻留于常规RAM(随机访问)区域,但可通过它的“”获得处理的直接支持。堆栈指针若向下移,会创建新的内存;若向上移,则会释放那些内存。这是一种特别快、特别有效的数据保存方式,仅次于寄存器。创建程序时,Java必须准确地知道堆栈内保存的所有数据的“长度”以及“存在时间”。这是由于它必须生成相应的代码,以便向上和向下移动。这一限制无疑影响了程序的灵活性,所以尽管有些Java数据要保存在堆栈里——特别是对象句柄,但Java对象并不放到其中。 堆 一种常规用途的(也在RAM区域),其中保存了Java对象。和不同,“内存堆”或“堆”(Heap)最吸引人的地方在于不必知道要从堆里分配多少,也不必知道存储的数据要在堆里停留多长的时间。因此,用堆保存数据时会得到更大的灵活性。要求创建一个对象时,只需用new命令编制相关的代码即可。执行这些代码时,会在堆里自动进行数据的保存。当然,为达到这种灵活性,必然会付出一定的代价:在堆里分配存储空间时会花掉更长的时间! 静态存储 这儿的“静态”(Static)是指“位于固定位置”(尽管也在RAM里)。程序运行期间,静态存储的数据将随时等候调用。可用static指出一个对象的特定元素是静态的。但Java对象本身永远都不会置入静态。 常数存储 常数值通常直接置于程序代码内部。这样做是安全的,因为它们永远都不会改变。有的常数需要严格地保护,所以可考虑将它们置入(ROM)。 非RAM存储 若数据完全独立于一个程序之外,则程序不运行时仍可存在,并在程序的控制范围之外。其中两个最主要的例子便是“流式对象”和“固定对象”。对于流式对象,对象会变成,通常会发给另一台机器。而对于固定对象,对象保存在中。即使程序中止运行,它们仍可保持自己的状态不变。对于这些类型的数据存储,一个特别有用的技巧就是它们能存在于其他媒体中。一旦需要,甚至能将它们恢复成普通的、基于RAM的对象。