运行时数据区域
java运行时数据区域主要分为下面几个:
方法区
虚拟机栈
本地方法栈
堆
程序计数器
java运行时数据区域.jpg
程序计数器
它是一块较小的内存空间,可以看做是当前线程所指定的字节码的行号指示器。字节码解释器工作时就是通过它选取下一条指令的。对于每条线程都有自己独立的程序计数器,所以该区域是线程私有的内存。
如果线程执行的是一个java方法,那么它存储的是正在执行的虚拟机字节码指令的地址;如果执行的是一个Native方法,则存储的值为空。这个区域是Java虚拟机规范中唯一没有规定任何OutOfMemory区域。
java虚拟机栈
它同程序计数器一样时线程私有的。虚拟机栈描述的是Java方法执行的内存模型:每一个方法执行时都会创建一个栈帧用于存放局部变量表、操作数栈、动态链接、方法出口等信息。每一个方法调用都对应着一个栈帧在虚拟机中入栈到处找的过程。
在此区域中Java虚拟机规范中定义了两种异常:如果请求栈深度大于虚拟机所允许的深度,将抛出StackOverflowError异常;如果栈是可以动态扩展的,在申请不到足够的内存时也会抛出OutOfMemoryError异常。
本地方法栈
它的作用同java虚拟机栈类似,只不过本地方法栈是为Native方法服务的。Java虚拟机规范没有限制本地方法栈的语言实现,它同样也会抛出StackOverflowError和OutOfMemoryError。
Java堆
Java堆是被所有线程共享的一块内存区域。此区域的唯一作用就是用来存放对象实例,几乎所有的对象实例都是在该区域分配的。
Java堆是垃圾收集器的主要区域。它可以是物理上不连续的内存空间,只要在逻辑上是连续的就行。它的大小可以是固定的,也可以动态扩展的。目前主流实现都是可扩展的,通过(-Xmx和-Xms控制)。如果在堆中没有内存可以完成实例分配,切堆也无法再扩展时将抛出OutOfMemoryError。
方法区
方法区与Java堆一样也是线程共享的内存区域,它用户存储已被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。
该区域在HotSpot虚拟机中使用的永久代来实现方法区,所以有时也被称作“永久代”。但是实际上该区域在Java虚拟机中并未详细指出如何实现,它也并不是永久的。
它和Java堆一样不需要连续的内存和可以选择固定大小或者可扩展外,还可以选择不实现垃圾收集。因为该区域主要针对的是常量池的回收和类型卸载,一般来说这个区域垃圾回收的效果不会很好。
总结
区域
方法区
java堆
本地方法栈
虚拟机栈
程序计数器
是否线程共享
是
是
否
否
否
作用
存放被虚拟机加载的类、常量、静态变量和即时编译后的代码等。
存放对象实例。
用来描述Native方法执行的内存模型。
用来描述java方法执行的内存模型。
当前线程所执行字节码的行号指示器。
异常类型
OutOfMemory
OutOfMemory
StackOverflow和OutOfMemory
StackOverflow和OutOfMemory
无