1.Java虚拟机栈----------------------------
我们常说java内存分为栈内存和堆内存,其实这个说法是比较粗糙的,java内存区域的划分其实远比这复杂,而这种划分的说法的流行只能说明大多数程序员最关注的、与对象内存分配关系最密切的区域是这两块,这里的栈其实叫虚拟机栈,因为还有一个栈叫本地方法栈,我们先说虚拟机栈(java Virtual Machine Stacks),
1.它是线程私有的,它的生命周期与线程相同;
2.它描述的是java方法执行的内存模型:每个方法在执行的同时都会创建一个栈帧(stack frame)用于存储局部变量表、操作数栈、动态链表、方法出口等信息。
3.每个方法从调用到执行结束的过程,就对应着一个栈帧在虚拟机栈中入栈到出栈的过程。
我们常说的这个栈,主要说的就是虚拟机栈中局部变量表的部分:
1.局部变量表存放了编译期可知的各种基本数据类型(boolean、byte、char、short、int、float、long、double)、对象的引用(reference类型)和returnAddress类型。
2.其中的64位长度的long和double类型的数据会占2个局部变量空间,其余的数据类型只占用1个。
3.布局变量表所需的内存空间在编译期间会完成分配,在方法运行期间不会改变局部变量表的大小。
4.栈有两种异常状况:
1.如果线程请求的栈深度大于虚拟机所允许的深度,将抛出stackOverflowError异常;
2.如果虚拟器动态扩展时无法申请到足够的内存,就会抛出OutOfMemoryError异常。
5.本地方法栈和虚拟机栈的作用非常相似,区别是虚拟机栈为虚拟机执行java方法,而本地方法栈为虚拟机使用 到的Native方法服务。
2.Java堆----------------------------
对于大多数应用来说,java堆是java虚拟机所托管的内存中最大的一块:
1.java堆是被所有的线程共享的一块内存区域,在虚拟机启动时创建。
2.此内存区域的唯一目的就是存放内存对象实例,几乎所有(注意不是绝对)的对象实例都在这里分配内存;
3.java堆是垃圾回收器的管理的主要区域,就是GC堆,由于现在回收器基本采用分代收集算法,所以java堆还可以分为新生代和老年代,不过无论如何划分,存储的都仍然是对象实例,进一步划分的目的是为了更好地回收内存和更快地分配内存。
4.如果在堆中没有完成实例分配,并且堆也无法再扩展时,将会抛出OutOfMemoryError异常
3.方法区----------------------------
方法区(Method Area)与Java堆一样,是各个线程共享的内存区域,它用于存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。虽然java虚拟机规范把方法区描述为堆的一个逻辑部分,但是它却有一个别名叫Non-Heap(非堆),目的是与java堆区分开来。