运行时数据区
概述
内存是非常重要的系统资源,是磁盘和CPU之间的桥梁,承载着操作系统和应用程序的实时运行。
JVM内存布局规定了Java在运行过程中内存申请、分配、管理的策略,保证了JVM的高效稳定运行。
不同的JVM对于内存的划分方式和管理机制存在着差异。
Java虚拟机定义了若干种程序运行期间会使用到的运行时数据区,其中有一些随着虚拟机启动而创建,随着虚拟机退出而销毁,另外一些则是与线程一一对应,随着线程的创建而创建,随着线程的销毁而销毁。
- 线程私有:程序计数器、虚拟机栈、本地栈
- 线程共享:堆、堆外内存如永久代或元空间、代码缓存
结构图
线程
线程是程序里面的运行单元,JVM允许一个应用程序有多个并行执行的线程。
在Hotspot JVM里面,每个线程都与操作系统的本地线程直接映射。当一个Java线程准备好执行后,此时操作系统本地线程同时创建,Java线程执行完毕,本地线程也会回收。
操作系统负责所有线程的调度到任何一个可以使用的CPU上。一旦本地线程初始化成功,就会调用Java的run方法。
JVM系统线程
虚拟机线程:这种线程的操作需要JVM到达安全点才会出现,这些操作必须在不同的线程中发生的原因是他们需要JVM到达安全点,这样堆才不会变化。这种线程的执行类型包括垃圾收集、线程栈收集、线程挂起和偏向锁撤销。
周期任务线程:这种线程是时间周期事件的体现,比如中断,他们一般用于周期性操作的调度执行。
GC线程:垃圾收集支持。
编译线程:在运行时将字节码编译成本地代码。
信号调度线程:接收信号并发送给JVM,在它内部通过调用适当的方法进行处理。
寄存器 - 程序计数器
概述
Program Counter Register - 程序计数寄存器。
源于CPU寄存器。
JVM的PC寄存器是对物理PC寄存器的一种抽象模拟。
用来存储指向下一条指令的地址,也就是即将执行的指令代码。
介绍
一块很小的内存空间,运行速度最快。
在JVM规范中,每个线程都有自己的程序计数器,是线程私有的,生命周期和线程保持一致。
任何时间一个线程都只有一个方法在执行,也就是当前方法。程序计数器会存储当前线程正在执行的Java方法的JVM指令地址,或者,如果是在执行native方法,则是undefined未指定值。
是程序控制流的指示器,分支、循环、跳转、异常处理、线程恢复等基础功能都依赖这个程序计数器来实现。
字节码解释器工作时就是通过改变这个计数器的值来选取下一条需要执行的字节码指令。
他是唯一没有规定任何OOM情况的区域。
示例
有什么用
因为CPU是不停切换线程的,当CPU切换回来需要知道之前执行到了哪里,寄存器就是记录下一条待执行指令的。
为什么是线程私有
- 避免覆盖
- 避免线程安全问题