文章目录
- PC Register
- 堆
- 虚拟机栈
- 方法区(Metaspace元空间
- 双亲委派机制
- 类加载器
- 类装载的执行过程
PC Register
程序计数器(Program Counter Register)是 Java 虚拟机(JVM)中的一个组件,它在 JVM 的内存模型中扮演着非常重要的角色。程序计数器是一块较小的内存空间,它的作用可以简单概括为:
-
存储指令地址:程序计数器用于存储指向下一条指令的地址,即当前线程执行的字节码的行号指示器。因为 JVM 执行的是字节码,所以程序计数器中存储的是字节码指令的地址。
-
线程私有:每个线程都有自己的程序计数器,这意味着它是线程私有的内存区域。这确保了在多线程环境中,不同线程执行的指令不会相互干扰。
-
上下文切换:在多线程环境中,当线程从执行状态切换到等待状态或被阻塞时,JVM 需要保存当前线程的程序计数器的值,以便在线程重新获得 CPU 时间片时能够从上次停止的地方继续执行。
-
分支跳转:程序计数器还负责分支跳转,比如循环、条件判断、方法调用等。当执行跳转指令时,程序计数器会更新为跳转目标的地址。
-
异常处理:在异常发生时,程序计数器也用于确定异常发生的位置,以便异常处理机制能够正确地捕获和处理异常。
程序计数器是 JVM 内存模型中唯一没有规定任何OutOfMemoryError(内存溢出错误)的区域。这是因为程序计数器的内存空间通常非常小,仅用于存储一个地址值,因此不存在内存不足的情况。
在实际的 JVM 实现中,程序计数器可能不直接以一个单独的内存区域存在,而是通过其他方式实现,比如在线程的栈中维护一个指向当前执行字节码指令的指针。无论如何实现,程序计数器的核心功能和作用都是相同的。
堆
jdk8和jdk7的区别?
永久代挪到了本地内存的元空间区域,是java八的优化,防止堆内存设置小了,导致存储的静态变量,常量,类信息爆空间,设置大了又浪费内存空间,直接放到本地内存里面就完事儿了!
堆主要还是保存对象和数组。
如果对象被GC多次之后依然存活,那么会从伊甸园区(Eden)挪到s0,再挪到s1,最后挪到老年代区。
s0和s1是幸存者区域(survivor区)
虚拟机栈
方法区(Metaspace元空间
jdk8,永久代变成MetaSpace元空间,占用本地内存
元空间主要还是存储类信息,静态变量,常量,编译好的代码
双亲委派机制
java会把源代码编译为字节码,再由类加载系统加载到运行时数据区
类加载器
类加载器:吧字节码文件加载到JVM内存里面
-
当加载一个类时,先判断此类是否已经被加载,如果类已经被加载则返回;
-
如果类没有被加载,则先委托父类加载(父类加载时会判断该类有没有被自己加载过),如果父类加载过则返回;如果没被加载过则继续向上委托;
-
如果一直委托都无法加载,子类加载器才会尝试自己加载。
类装载的执行过程
标红的表示当前执行到的阶段