1.程序计数器 作用是可以看做当前线程执行的字节码的行号指示器,字节码解析工作的时候,通过改变程序计数器的值来选择下一条需要执行的字节码指令。java虚拟机的多线程是通过线程轮流切换并分配处理器执行时间片来实现的,在任何一个时刻,一个处理器只会执行一条线程命令的,因此为了确保线程切换之后恢复到正确的执行位置,每条线程都需要一个独立的程序计数器,所以,程序计数器是私有的,而且是java中唯一没有规定任何内存溢出的内存区域 2.JVM栈,java虚拟栈,线程私有,它的生命周期和线程相同,虚拟机栈描述的是java方法执行的内存模式的,每个方法被执行时都会创建一个栈帧来存放局部变量表,操作数栈,动态链接和方法的出口信息。每个方法被调用直到执行完成的过程,就对应着一个栈帧在虚拟机中的出入栈的。java虚拟机栈的局部变量表保存了编译器可知的8种java基本的类型数据,对象引用(注意不是对象实例本身),方法返回的地址,局部变量表所需要的内存空间在编译器就进行好分配的,当进入一个方法的时候,该方法需要在栈帧里面分配多大的局部变量空间完全确定的,在方法运行期间不会改变局部变量表的大小的。java虚拟机栈有两种异常情况,如果单线程请求的栈的深度大于虚拟机栈所允许的最大深度,就会抛出StackOverFlowError异常,如果虚拟机栈是可以动态扩展的,当扩展无法申请到足够内存的话,就会抛出OutOfMemoryError. 3.本地方法栈,本地方法栈与java虚拟机栈作用是非常类似的,区别是:java虚拟机栈是为虚拟机执行java服务的,而本地方法栈是为虚拟机调用的操作系统本地方法服务的。java虚拟机规范没有对本地方法栈的实现和数据结构做强制的规定的,Sun HotSpot虚拟机直接把java虚拟机和本地方法栈合二为一的。 4.共享堆,堆是java虚拟机所管理的内存区域最大的一块,java中堆是被所有线程所共享的一块内存区域,在java虚拟机启动的时候创建,堆内存的唯一目的就是存放对象实例的,几乎所有对象实例都是在堆内存分配的。java堆也是垃圾收集器主要管理的区域。从垃圾回收的角度来看,由于现在的垃圾收集器都采用了分代收集算法,因此java堆可以初步细分为新生代和年老代的。java虚拟机规范规定,堆可以处于物理上不连续的内存空间中,只要逻辑上是连续的就可以的。在实现上既可以是固定大小,也可以是动态扩展的。如果在堆中没有内存完成实例分配,并且堆大小也无法再扩展时,就会抛出outofMemoryError异常 5.方法区:方法区与堆一样都是共享的。用于存储已被虚拟机加载的类信息,常量,静态变量,即时编译后的代码数据,虽然java虚拟机规范把方法区描述为堆的一个逻辑部分,但是方法区却有一个别名NOn--Heap(非堆), Sun HotSpot 虚拟机把方法区叫做永久代,方法区中最重要的是运行时常量池。class 文件中除了有类的版本,字段,方法,接口等描述信息外,还有一项信息是常量池,用于存放编译期间生成的各种字面变量,符号引用,直接引用等,这些内容将在类加载后存放到方法区的运行时常量池,另外在运行期间也可以将新的常量存放到常量池中的