目录
首先来看一下JVM运行时数据区有哪些。
在介绍JVM栈之前,先了解一下?栈帧?概念。
栈帧:一个栈帧随着一个方法的调用开始而创建,这个方法调用完成而销毁。栈帧内存放者方法中的局部变量,操作数栈等数据。
Java栈也称作虚拟机栈(Java Vitual Machine Stack),JVM栈只对栈帧进行存储,压栈和出栈操作。
Java栈是Java方法执行的内存模型。下面我们来看一个Java栈图。
Java栈中存放的是一个个的栈帧,每个栈帧对应一个被调用的方法,在栈帧中包括局部变量表(Local Variables)、操作数栈(Operand Stack)、指向当前方法所属的类的运行时常量池(运行时常量池的概念在方法区部分会谈到)的引用(Reference to runtime constant pool)、方法返回地址(Return Address)和一些额外的附加信息。
当线程执行一个方法时,就会随之创建一个对应的栈帧,并将建立的栈帧压栈。当方法执行完毕之后,便会将栈帧出栈。
因此可知,线程当前执行的方法所对应的栈帧必定位于Java栈的顶部。
对于所有的程序设计语言来说,栈这部分空间对程序员来说是不透明的。?
栈内存的大小可以有两种设置,固定值和根据线程需要动态增长。
在JVM栈这个数据区可能会发生抛出两种错误。
总结
堆数据区是用来存放对象和数组(特殊的对象)。堆内存由多个线程共享。堆内存随着JVM启动而创建。
众所周知,Java中有一个很好的特性就是自动垃圾回收。垃圾回收就操作这个数据区来回收对象进而释放内存。
如果堆内存剩余的内存不足以满足于对象创建,JVM会抛出OutOfMemoryError错误。
总结
方法区在JVM中也是一个非常重要的区域,它与堆一样,是被线程共享的区域。
在方法区中,存储了每个类的信息(包括类的名称、方法信息、字段信息)、静态变量、常量以及编译器编译后的代码等。
在Class文件中除了类的字段、方法、接口等描述信息外,还有一项信息是常量池,用来存储编译期间生成的字面量和符号引用。
在方法区中有一个非常重要的部分就是运行时常量池,它是每一个类或接口的常量池的运行时表示形式,在类和接口被加载到JVM后,对应的运行时常量池就被创建出来。
当然并非Class文件常量池中的内容才能进入运行时常量池,在运行期间也可将新的常量放入运行时常量池中,比如String的intern方法。
一个支持native方法调用的JVM实现,需要有这样一个数据区,就是本地方法栈。
Java官方对于本地方法的定义为methods written in a language other than the Java programming language,就是使用非Java语言实现的方法,但是通常我们指的一般为C或者C++,因此这个栈也有着C栈这一称号。
一个不支持本地方法执行的JVM没有必要实现这个数据区域。
本地方法栈基本和JVM栈一样,其大小也是可以设置为固定值或者动态增加,因此也会对应抛出StackOverflowError和OutOfMemoryError错误。
在HotSopt虚拟机中直接就把本地方法栈和Java栈合二为一。
在通用的计算机体系中,程序计数器用来记录当前正在执行的指令,在JVM中也是如此。
程序计数器是线程私有,所以当一个新的线程创建时,程序计数器也会创建。
由于Java是支持多线程,Java中的程序计数器用来记录当前线程中正在执行的指令。
如果当前正在执行的方法是本地方法,那么此刻程序计数器的值为undefined。
注意这个区域是唯一一个不抛出OutOfMemoryError的运行时数据区。
?
参考自:https://blog.csdn.net/zhangqilugrubby/article/details/59110906