堆和堆栈的区别
详见: http://www.iteye.com/problems/34966
heap(堆) :
JVM 的内存数据区. 用来保存对象的实例.
在堆中分配一定的内存来保存对象实例, 实际上是保存对象实例的属性值、属性的类型和对象本身的类型标记等,
并不保存对象的方法(方法是指令, 保存在 栈 中).
对象实例在堆中分配好以后, 会在 栈 中保存一个 4 字节的堆内存地址
用来定位该对象实例在堆中的位置, 便于找到该对象实例.
stack(栈) :
JVM 的内存指令区: Java 基本数据类型, Java 指令代码, 常量都保存在 栈 中.
“ 栈” 的内存管理不存在内存回收问题(而 “堆” 则是随机分配内存, 存在内存分配和回收的问题 )
GC 会不定期扫描堆, 根据“栈”中保存的 4 字节对象地址扫描“堆”, 定位“堆”中这些对象,
进行一些优化(例如合并空闲内存块什么的), 并且假设堆中没有扫描到的区域都是空闲的, 统统垃圾收集.
=========================分割线=============================
JVM中的堆和栈
JVM是基于堆栈的虚拟机.JVM为每个新创建的线程都分配一个堆栈.也就是说,对于一个Java程序来说,它的运行就是通过对堆栈的操作来完成的。堆栈以帧为单位保存线程的状态。JVM对堆栈只进行两种操作:以帧为单位的压栈和出栈操作。
我们知道,某个线程正在执行的方法称为此线程的当前方法.我们可能不知道,当前方法使用的帧称为当前帧。当线程激活一个Java方法,JVM就会在线程的 Java堆栈里新压入一个帧。这个帧自然成为了当前帧.在此方法执行期间,这个帧将用来保存参数,局部变量,中间计算过程和其他数据.这个帧在这里和编译原理中的活动纪录的概念是差不多的.
从Java的这种分配机制来看,堆栈又可以这样理解:
堆栈(Stack)是操作系统在建立某个进程时或者线程(在支持多线程的操作系统中是线程)为这个线程建立的存储区域,该区域具有先进后出的特性。每一个Java应用都唯一对应一个JVM实例,每一个实例唯一对应一个堆。应用程序在运行中所创建的所有类实例或数组都放在这个堆中,并由应用所有的线程共享.跟C/C++不同,Java中分配堆内存是自动初始化的。
Java中所有对象的存储空间都是在堆中分配的,但是这个对象的引用却是在堆栈中分配,
也就是说在建立一个对象时从两个地方都分配内存,在堆中分配的内存实际建立这个对象,而在堆栈中分配的内存只是一个指向这个堆对象的指针(引用)而已。