Java虚拟机(JVM)在java程序运行过程中,会将它管理的内存划分成若干个不同的数据区域,这些区域有的随着jvm的启动而创建,有的随着用户线程的启动和结束而建立和销毁。

JAVA SE7 虚拟机规范: 方法区,堆、本地方法栈、虚拟机栈、程序计数器。

虚拟机规范并不是一成不变的,在发布新的jdk版本时,会进行优化和改进,jdk1.8中 方法区被移除, 取而代之的是mataspace 元数据空间。

1.什么事程序计数器

程序记录器是一个记录当前线程所执行字节码的行号指示器。

JAVA代码编译后的字节码,再未经JIT(实时编译器)编译前,其执行方式是通过字节码解释器进行解释执行的,简单的工作原理为解释器读取装载入内存的字节码。按照顺序读取字节码指令,读取指令后,将该指令翻译成固定的操作,并根据这些操作进行分支、循环、跳转等流程。

 

从上面的描述中可能会产生程序计数器是否多余的疑问。因为沿着指令顺序执行下去,即使是分支跳转这样的流程。跳转到指定的指令处,按顺序继续执行,是完全能保证执行顺序的,假设程序永远只有一个线程,这个疑问没有任何问题,也就是说不需要程序计数器,但程序是通过多个线程协同合作执行的。

首先我们要搞清楚JVM多线程的实现方式,jvm多线程是通过cup时间片轮转(即线程轮流切换,并分配处理器执行时间)算法实现的,也就是说,线程执行过程中会因为时间片耗尽而被挂起,而另一个线程获取到时间片而开始执行。当挂起线程重新获取到时间片的时候,它想从被挂起的地方继续执行。就必须知道它上次执行到了什么地方。在jvm中通过程序计数器来记录线程执行到字节码执行到哪个位置。因此程序计数器具有线程隔离的特性,也就是说每个线程都有自己的程序计数器。

 

 

程序计数器特点

1,线程隔离特性,每个线程工作时都有属于自己的独立计数器

2,在执行Java方法时,程序计数器是有值的,记录的刚好是正在执行的字节码指令的地址。

3,在执行native本地方法时,程序计数器的值为空,因为native方法时java 通过JNI 直接调用本地C/C++库,可以近似的任务native方法时c/c++暴露给java的一个接口,java通过这个接口调用c/c++,于该方法是通过C/C++而不是java进行实现。那么自然无法产生相应的字节码,并且C/C++执行时的内存分配是由自己语言决定的,而不是由JVM决定的。