栈(stack)与堆(heap)都是Java用来在Ram中存放数据的地方。与C++不同,Java自动管理栈和堆,程序员不能直接地设置栈或堆。
通俗的讲,堆主要用来存放对象的,即用来存放由new创建的对象和数组(即对象实例),然后由Java虚拟机的自动垃圾回收器来管理;栈主要是用来执行程序的,栈中主要存放一些基本类型的变量(int, short, long, byte, float, double, boolean, char),和对象句柄(即对象的引用地址),同时栈中的数据可以共享。
堆是由垃圾回收来负责的,堆的优势是可以动态地分配内存大小,生存期也不必事先告诉编译器,因为它是在运行时动态分配内存的,Java的垃圾收集器会自动收走这些不再使用的数据。但缺点是,由于要在运行时动态分配内存,存取速度较慢。
栈的优势是,存取速度比堆要快,仅次于直接位于CPU中的寄存器。但缺点是,存在栈中的数据大小与生存期必须是确定的(如存在某函数块中的局部变量,其生命周期即等到函数结束为止),缺乏灵活性。另外,栈数据可以共享。
总体来说,基本数据类型,方法的形式参数,直接在栈空间分配,当方法调用完成后从栈空间回收。引用数据类型,需要用new来创建,既在栈空间分配一个地址空间(对象的引用),又在堆空间分配对象的类变量。方法的引用参数,在栈空间分配一个地址空间,并指向堆空间的对象区,当方法调用完成后从栈空间回收。局部变量new出来时,在栈空间和堆空间中分配空间,当局部变量生命周期结束后,栈空间立刻被回收,堆空间区域等待GC回收 |