jvm深度学习(4):java方法的运行与程序计数器

程序计数器:

较小的内存空间,当前线程执行的字节码的行号指示器;各线程之间独立存储,互不影响。
程序计数器是一块很小的内存空间,主要用来记录本线程执行的字节码的地址,例如,分支、循环、跳转、异常、线程恢复等都依赖于计数器。
由于 Java 是多线程语言,当执行的线程数量超过 CPU 核数时,线程之间会根据时间片轮询争夺 CPU 资源。如果一个线程的时间片用完了,或者是其它原因导致这个线程的 CPU 资源被提前抢夺,那么这个退出的线程就需要单独的一个程序计数器,来记录下一条运行的指令。
因为 JVM 是虚拟机,内部有完整的指令与执行的一套流程,所以在运行 Java 方法的时候需要使用程序计数器(记录字节码执行的地址或行号),如果是遇到本地方法(native 方法),这个方法不是 JVM 来具体执行,所以程序计数器不需要记录了,这个是因为在操作系统层面也有一个程序计数器,这个 会记录本地代码的执行的地址,所以在执行 native 方法时,JVM 中程序计数器的值为空(Undefined)。
另外程序计数器也是 JVM 中唯一不会 OOM(OutOfMemory)的内存区域。

在上一节我们通过反汇编得到如下的代码:

上面标红的是指令的行号。

有些行号他不是连续的。我们知道事实上java的底层本质上还是C语言和C++去实现的,因此他们的计算方式是按照偏移量方式。有些指令偏移量过大,这就导致不连续的问题。

而我们的程序计数器所记录的就是行号,当线城阻塞,程序计数器记录着下一条指令的行号,当线城获得CPU资源时,虚拟机栈运行最顶上的栈帧,通过程序计数器记录的行号对应的指令开始执行。

有的人可能会问,线程是怎么该执行哪个方法,因为程序计数器只记录了行号,并没有记录是哪个方法。

我们要知道,栈遵从的是先进后出的原则,也就是线程阻塞之前在执行的栈帧一定在栈顶,而线程开始执行时就是从栈顶开始的,所以不需要记录。

 

声明:本文为学习享学课堂三期JVM章节课后所做的学习总结,文中借鉴King老师上课笔记和课堂PPT。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值