基于JDK1.8对JVM进行深入理解之运行时数据区(一)

本文基于JDK1.8环境,深入探讨JVM运行时数据区。JDK1.8后方法区被元空间取代,还详细介绍了程序计数器,它是较小且运行快的内存区域,支撑Java多线程,记录线程指令执行位置,且每个线程独有,还展示了其在Java程序中的体现。

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

基于JDK1.8的环境下对JVM的运行时数据区进行一次深入的理解,在JDK1.8之前运行时数据区的整个区域分配如下图所示:

在JDK1.8 之后,方法区就被永远的移除了,取而代之的是一个叫元空间(Meta Space)的内存区域,我就按照JAVA虚拟机规范一个个的对每个区域进行深入的理解

  • 程序计数器(The pc Register)

是一块较小的内存空间,但是也运行速度最快的一块内存空间。这块区域也对JAVA的多线程起到了支撑作用。

在JAVA的多线程执行过程中,实际上是线程进行CPU时间片的抢夺来争取执行线程中方法的指令。在多线程的情况下,线程A和线程B进行了资源争夺,在线程A执行了一条指令后,CPU时间片又被线程B争夺到,这个时候如果再切换回线程A,怎么能知道线程A执行到了哪里,又从哪里继续?程序计数器就是做了这么一个工作,记录了线程A的指令执行到了哪里,让CPU可以知道这个线程可以从哪里继续执行下去,所以每一个线程都会有一个自己的程序计数器独立存储,互不影响,随着线程的创建而创建,随着线程的消亡而消亡,这个区域算是线程私有的一个区域。

注:如果程序运行的是JAVA方法,则程序计数器记录的是当前正在执行的虚拟机字节指令的地址。如果是Native方法,则程序计数器的值则为空(undefined),这个区域是Java虚拟机规范中没有规定任何OutOfMemoryError情况的区域。

程序计数器在JAVA中的体现:

首先我们编写一个JAVA程序:

package utils;

public class Test{
    public statici void main(String[] args){
            int a = 1;
            int b = 2;
            System.out.println(a+b);
    }
}

将其通过javap -c命令反编译字节码,如下图所示

编译后的test.class 包括一个Test类的默认无参构造器以及一个编写的main方法

Code: 下的

0:iconst_1

1:istore_1

2:iconst_2

3:istore_2

4:getstatic  #2

第一列0/1/2 表示这程序计数器的指令地址,iconst_1内容则表示该行指令的具体指令字节码,第三列的#2是符号引用,解析后指向常量池具体引用,在栈帧中也叫动态连接,下文进一步了解这个内容

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值