本文主要是介绍JVM探秘之运行时数据区,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!
(图来自《深入理解java虚拟机》)
1、程序计数器(Program Counter Register)
- 可以比作当前线程所执行的字节码的行号指示器。
- 每条线程都需要有一个独立的程序计数器,线程私有的内存。
- 计数器记录的是正在执行的虚拟机字节码指令的地址;如果正在执行的是Native方法,这个计数器值就是空的。
2、Java虚拟机栈(Java Virtual Machine Stacks)
线程私有,Java方法执行的内存模型:每个方法在执行的同时都会创建一个栈帧用于存储局部变量表、操作数栈、动态链接、方法出口等信息。方法的调用到完成对应栈帧的入栈和出栈(debug递归方法可以看出)。
虚拟机栈的局部变量表存储了八大基本数据类型、对象引用类型和returnAddress类型(指向一条字节码指令的地址)。long型和double型占两个局部变量空间,其余类型只占一个。
- 线程请求的栈深度大于虚拟机所允许的深度,将抛出StackOverflowError异常。
3、本地方法栈(Native Method Stack)
- 为虚拟机使用到的native方法服务,区别于虚拟机栈的普通方法。
- 线程私有。
4、Java堆(Java Heap)
- 所有线程共享的内存区域。
- 唯一目的就是存放对象实例,所有的对象实例以及数组都要在堆上分配内存。
- Java堆是垃圾收集器管理的主要区域。
- 堆中没有内存完成实例分配,并且堆也无法再扩展时,将会抛出OutOfMemoryError异常。
5、方法区(Method Area)
- 各个线程共享的内存区域,存储被虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。
- HotSpot上,GC分代中将方法区俗称“永久代”。
- 当方法区无法满足内存分配需求时,将抛出OutOfMemoryError异常。
6、运行时常量池(Runtime Constant Pool)
- 方法区的一部分,用于存放编译期生成的各种字面量和符号引用。
- 运行期间也可能把新的常量加入运行时常量池,并不一定是编译时期才能产生,譬如String类的intern()方法。
- 当常量池无法申请到内存时,会抛出OutOfMemoryError异常。
总结
以上是java内存运行时区域的各个部分,其中程序计数器、虚拟机栈、本地方法栈3个区域随线程而生,随线程而灭。栈中的栈帧随着方法的进入和退出而有条不紊地执行着出栈和入栈操作。而堆和方法区中存储着线程共享的变量、常量、类信息等。
这篇关于JVM探秘之运行时数据区的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!