导读:
从今天开始,正式进入java的jvm中学习。jvm是什么?在早期的jdk版本颁布中就 第一时间发布了,称为java虚拟机。java和c++、c不同,它们有自己专属的自己回收垃圾机制,这样即便我们在不能很好的控制java虚拟机内存的时候,它们会帮我们解决这一系列的困惑,所以考虑到这点推出了自动回收管理机制。那么自动回收管理机制有什么用处呢?它们各模块之间怎么联系的呢?让我们慢慢细说。
一、什么是程序计数器
程序计数器(Program Counter Register)是一块较小的内存空间,它可以看作是当前线程所执行的字节码的行号指示器。在虚拟机的概念模型里(仅是概念模型,各种虚拟机可能会通过一些更高效的方式去实现),字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令,分支、循环跳转、异常处理、线程恢复等基础功能都需要依赖这个计数器赖完成。
——————摘自周志明的《深入理解Java虚拟机》
从上面的话中我们得到如下的信息:
- 当我们启动线程时,会有伴随一个独立的程序计数器,它可以用来记录线程的状态信息,这个是线程“私有”的内存。
- 线程是有生命周期的,线程销毁着毁掉该线程所持有的程序计数器。
- 该线程执行的是java方法才会有程序计数器 记录的正在执行的虚拟机字节码指令地址,否则如果是Native方法,则该计数器里不存在任何值(undefined类型),理由因为Native方法是java接口,由非java代码调用,也就是其他代码了,如C和C++
- 此内存区域是唯一一个在Java虚拟机规范中没有规定任何OutOfMemoryError情况的区域(OutOfMemoryErro指内存溢出)
二、什么是程序计数器中的字节码指令的偏移地址
在操作系统中,偏移地址指的是计算机里的内存分段后,在段内某一地址相对于段首地址(段地址)的偏移量。现在,我们随意建立一个简单的java文件进行举例。如下代码
package com.test;
public class cl {
public int al(){
int a = 50;
int c = 50;
int b = 50;
return (a + b)*c;
}
}
我们在运行java编译后的.class文件后通过操作系统反编译得到的汇编语言如下:
这就是所谓的字节码的偏移地址了,这些命令也是入栈的命令。那么我们的程序计数器里面的数字有什么意义吗?我的理解是类似于记录线程的状态,比如,我们现在有五个线程,每个线程的状态和进度都是不同的,现在我们一回合的循环已经确定了个线程的状态,此时线程的独立的程序计数器都记录了他们自己当前的状态。当时间片轮转后,重新从第一个开始依线程然是它的进度。当然这样我们会感受得到吗?答案是感受不到的,因为间隔时间相当短,就好像没有进行轮转一样。
延伸知识:
1.对Native的理解*
Native是java提供的一个接口,Java平台有个用户和本地C代码进行互操作的API,称为Java Native Interface (Java本地接口)。在磁盘中,我们给一部分的内存给jvm,其余的都是非jvm区域,所以在调用native会告诉jvm:我的方法不在你那里定义,我的方法可能在C或者C++里面定义。Native这个接口可以接轨其他语言,这个是极好的,java语言可以往外延伸,大家语言编写的功能各管各的,但是我可以调用你的接口执行我自己的方法。也就是说在jdk版本升级的过程中,语言的互通性也在加强。