JVM运行时数据区域
下图是JVM运行时内存结构图,主要包含5部分
1.方法区
方法区是所有线程共享的。方法区存储每个类的运行时常量池,field,方法数据,方法和构造器的代码等。逻辑上是属于堆的一部分,但可以不用被垃圾收集器管理。方法区内存也不一定是连续的。方法区大小可以固定,也可以够动态扩展,由具体实现来定。如果内存不够做分配,则会导致内存溢出(OutOfMemoryError)。
1.1.运行时常量池
这里说的运行时常量池就是在方法区中的。运行时常量池包括类或者接口class文件中定义的常量池表,也可包含运行时才解析的方法或者field引用。如果常量池需要的内存,方法区不能分配,则会导致内存溢出(OutOfMemoryError)。
2.堆
堆空间是线程共享的,用于类实例或者数组的创建。由垃圾收集器管理,具体的垃圾收集器类型,Java虚拟机规范也没有指定,由实现者决定。堆的空间也不一定是连续的。如果线程需要分配对象的空间大于可用的堆空间,则会导致内存溢出(OutOfMemoryError)。
3.虚拟机栈
每个线程有独自的虚拟机栈。虚拟机栈存储栈帧(方法)、局部变量和部分结果。另外,虚拟机栈可能不是连续的。虚拟机栈的大小是固定的还是可扩展的,Java虚拟机规范没有规则,由各个虚拟机实现自己决定。如果线程申请的虚拟机栈大于允许的值,则会导致栈溢出(StackOverflowError)。如果虚拟机栈可以扩展,但已经没有足够的内存可以使用,则会导致内存溢出(OutOfMemoryError)。
4.程序计数器
每个线程有独自的程序计数器。如果不是native方法,程序计数器包含当前虚拟机执行的指令的地址
5.本地方法栈
虚拟机可以不提供本地方法栈(如没法加载native方法),但如果提供了,则每个线程有自己分配自己的本地方法栈。如果线程需要一个大小大于虚拟机允许的本地方法栈,则会导致栈溢出(StackOverflowError)。如果本地方法栈可以扩展,但已经没有足够的内存可以使用,则会导致内存溢出(OutOfMemoryError)
reference: