JVM 运行时数据区域

 JDK1.8 JVM运行时数据区域概览

è¿éåå¾çæè¿°

 

 程序计数器

程序计数器(Program Counter Register) 是一块较小的(各线程私有的)内存空间, 它可以看作是当前线程所执行的字节码的行号指示器。

字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令, 它是程序控制流的指示器, 分支、 循环、 跳转、 异常处理、 线程恢复等基础功能都需要依赖这个计数器来完成。

每条线程都需要有一个独立的程序计数器, 各条线程之间计数器互不影响, 独立存储, 我们称这类内存区域为“线程私有”的内存。

Java虚拟机栈

Java虚拟机栈(Java Virtual Machine Stack) 也是线程私有的, 它的生命周期与线程相同。

每个方法被执行的时候, Java虚拟机都会同步创建一个栈帧(Stack Frame) 用于存储局部变量表、 操作数栈、 动态连接、 方法出口等信息。

stack

局部变量表

局部变量表存放了编译期可知的各种Java虚拟机基本数据类型(boolean、 byte、 char、 short、 int、float、 long、 double) 、 对象引用(reference类型, 它并不等同于对象本身, 可能是一个指向对象起始地址的引用指针, 也可能是指向一个代表对象的句柄或者其他与此对象相关的位置) 和 returnAddress类型(指向了一条字节码指令的地址) 。

创建对象

会在堆内存中开辟一块内存,用来存储p对象的所有内容,然后再栈内存中创建一个引用p存储堆区中p对象的真实地址,如下图:

本地方法栈

本地方法栈(Native Method Stacks) 与虚拟机栈所发挥的作用是非常相似的, 其区别只是虚拟机栈为虚拟机执行Java方法(也就是字节码) 服务, 而本地方法栈则是为虚拟机使用到的本地(Native)方法服务。

Java堆

Java堆(Java Heap) 是虚拟机所管理的内存中最大的一块。 Java堆是被所有线程共享的一块内存区域, 在虚拟机启动时创建。 此内存区域的唯一目的就是存放对象实例, Java世界里“几乎”所有的对象实例都在这里分配内存。

Java堆是垃圾收集器管理的内存区域, 也被称作“GC堆”。

Java堆中可以划分出多个线程私有的分配缓冲区,将Java堆细分的目的只是为了更好地回收内存, 或者更快地分配内存。Java堆可以处于物理上不连续的内存空间中, 但在逻辑上它应该被视为连续的。

方法区

方法区(Method Area) 与Java堆一样, 是各个线程共享的内存区域, 它用于存储已被虚拟机加载的类型信息、 常量、 静态变量、 即时编译器编译后的代码缓存等数据。

JDK 8以前,把方法区称呼为“永久代”(PermanentGeneration)。到了JDK 8, 终于完全废弃了永久代的概念, 改用在本地内存中实现的元空间(Metaspace)

运行时常量池

运行时常量池(Runtime Constant Pool) 是方法区的一部分。 Class文件中除了有类的版本、 字段、 方法、 接口等描述信息外, 还有一项信息是常量池表(Constant Pool Table) , 用于存放编译期生成的各种字面量与符号引用, 这部分内容将在类加载后存放到方法区的运行时常量池中。

直接内存

直接内存(Direct Memory),在JDK 1.4中新加入了NIO(New Input/Output) 类, 引入了一种基于通道(Channel) 与缓冲区(Buffer) 的I/O方式, 它可以使用Native函数库直接分配堆外内存, 然后通过一个存储在Java堆里面的DirectByteBuffer对象作为这块内存的引用进行操作。

 

 


学习参考:

《深入理解Java虚拟机: JVM高级特性与最佳实践(第3版)》

JDK1.8 JVM运行时数据区域划分 https://blog.csdn.net/bruce128/article/details/79357870

Java——值传递和引用传递 https://www.cnblogs.com/wugongzi/p/11297638.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值