JVM运行时数据区图解(总结自《深入理解Java虚拟机》)

本文详细介绍了JVM的运行时数据区,包括程序计数器、Java虚拟机栈、本地方法栈、Java堆、方法区、运行时常量池和直接内存。每个区域的功能、线程共享情况以及与内存分配和垃圾收集的关系都进行了阐述。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

*** 本文内容源自《深入理解JAVA虚拟机》整理而得。

JVM运行时数据区基本组成部分及其功能:
在这里插入图片描述
*灰色部分为线程共享
*蓝色部分为线程私有

1. 程序计数器

程序计数器(Program Counter Register)可以看作是当前线程所执行字节码的行号指示器。字节码解释器工作时就是通过改变这个计数器的值Laura选取吓一跳需要执行的字节码指令。

Java虚拟机的多线程是通过线程轮流切换、分配处理器执行时间的方式来实现的,在任何一个确定的时刻,一个处理器(单核)都只会执行一条线程中的指令。程序计数器可用于线程切换后能恢复到正确的执行位置,每条线程都需要一个独立的程序计数器,各条线程之间计数器互不影响,独立存储。因此程序计数器为线程私有

  • 如果线程正在执行的是一个Java方法,这个计数器记录的是正在执行的虚拟机字节码指令的地址
  • 如果正在执行的是本地(Native)方法,这个计数器值则应为空。
2. Java虚拟机栈

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

每个方法被执行的时候,Java虚拟机都会同步创建一个栈帧(Stack Frame)用于存储局部变量表、操作数栈、动态连接、方法出口等信息。每一份方法被调用直至执行完毕的过程,对应栈帧在虚拟机栈从入栈到出栈的过程。

3. 本地方法栈

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

4. Java堆

Java堆被所有线程共享,在虚拟机启动时创建。Java堆的唯一目的就是存放对象实例

Java堆是垃圾收集器管理的内存区域。

从分配内存的角度看,Java堆可以划分出多个线程私有的分配缓冲区(Thread Local Allocation Buffer), 简称TLAB,用于提升对象分配时的效率。

5. 方法区

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

这个区域内存回收目标主要是针对常量池的回收和对类型的卸载,一般来说回收效果比较难令人满意。

如果方法区无法满足新的内存分配需求,将抛出OutOfMemoryError异常。

6. 运行时常量池

运行时常量池(Runtime Constant Pool)是方法区的一部分。

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

因为运行是常量池是方法区的一部分,当常量池无法申请到内存时会抛出OutOfMemoryError异常。

7. *直接内存

直接内存(Direct Memory)并不是虚拟机运行时数据区的一部分。但是这部分也被频繁使用,而且也可能导致OutOfMemoryError异常出现。

*** 本文内容为《深入理解JAVA虚拟机》总结整理而得。

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值