内存结构

前言简介程序计数器定义作用特点示例应用场景

主页传送门: 传送

前言

Java 虚拟机的内存空间由 堆、栈、方法区、程序计数器和本地方法栈五部分组成。

简介

  JVM(Java Virtual Machine)内存结构包括以下几个部分:

堆区(Heap):堆区是最大的一块内存区域,由所有线程共享。所有的对象实例以及数组都在这块内存中分配。方法区(Method Area):方法区用于存储已被 JVM 加载的类信息、常量、静态变量,以及即时编译器编译后的代码等数据。栈(Stack):每个线程在创建时都会创建一个 JVM 栈,每个方法在执行的时候都会创建一个栈帧,用于存储局部变量、操作数栈、动态链接、方法出口等信息。程序计数器(Program Counter Register):这是一块较小的内存空间,可以看作是当前线程所执行的字节码指令的行号指示器。本地方法栈(Native Method Stack):与 JVM 栈类似,但是本地方法栈主要用于执行本地方法。

图示如下:

  JDK 1.8 同 JDK 1.7 比,最大的差别就是:元数据区取代了永久代。元空间的本质和永久代类似,都是对 JVM 规范中方法区的实现。不过元空间与永久代之间最大的区别在于:元数据空间并不在虚拟机中,而是使用本地内存。

程序计数器

定义

  程序计数器(PC 寄存器)是一块较小的内存空间,它是一个专用的寄存器,用于存储当前正在执行的指令在指令序列中的位置。

作用

按照顺序依次执行指令序列中的指令,当执行到跳转指令时,需要根据跳转指令的目标地址更新程序计数器的值,以便下一条指令能够正确执行。实现异常处理和中断服务。当程序出现异常或被中断时,程序计数器的值会被保存下来,以便在异常或中断处理结束后能够正确地继续执行程序。

特点

线程隔离性:每个线程拥有自己的程序计数器,一个线程无法直接访问和修改另一个线程的程序计数器。内存占用小:程序计数器占用的内存空间非常小,可以忽略不计。无OutofMemoryError:程序计数器是Java虚拟机规范中唯一一个没有规定任何OutOfMemoryError的区域。执行时有值:程序执行的时候,程序计数器有值,其记录的是程序正在执行的字节码的地址。执行本地方法时值为空:执行native本地方法时,程序计数器的值为空。原因是native方法是Java通过jni调用本地C/C++库来实现,非Java字节码实现,所以无法统计。

示例

public class ProgramCounterExample {

public static void main(String[] args) {

ProgramCounter pc = new ProgramCounter();

pc.increment();

System.out.println(pc.getValue()); // 输出 1

pc.decrement();

System.out.println(pc.getValue()); // 输出 0

pc.setValue(pc.getValue() + 1);

System.out.println(pc.getValue()); // 输出 1

}

}

class ProgramCounter {

private int value;

public ProgramCounter() {

value = 0;

}

public void increment() {

value++;

}

public void decrement() {

value--;

}

public int getValue() {

return value;

}

public void setValue(int value) {

this.value = value;

}

}

应用场景

指令执行控制:程序计数器可以用于实现指令流水线,即每条指令执行时,程序计数器会自动增加,指向下一条要执行的指令。实现跳转:当程序执行到跳转指令时,程序计数器需要根据跳转指令的目标地址更新自身的值,以便下一条指令能够正确执行。实现异常处理和中断服务:当程序出现异常或被中断时,程序计数器的值会被保存下来,以便在异常或中断处理结束后能够正确地继续执行程序。实现多线程:在多线程环境中,每个线程拥有自己的程序计数器,用于记录该线程正在执行的指令序列。

如果喜欢的话,欢迎 爛关注 点赞 评论 欄收藏 一起讨论

你的支持就是我✍️创作的动力! 

好文推荐

评论可见,请评论后查看内容,谢谢!!!
 您阅读本篇文章共花了: