每天每天
越来越爱

jvm运行时数据区及线程理解 jvm运行时数据区与线程理解

运行时数据区

https://www.mamq.top/wp-content/uploads/2022/10/f6c83bec90974ab2b54c644e05f869d8.png

包括:程序计数器(PC寄存器)、Java虚拟机栈、Java堆、方法区、运行时常量池、本地方法栈等等。

程序计数器

程序计数器也叫做PC寄存器

  • JVM支持多个线程同时运行,每个线程拥有一个程序计数器,是线程私有的,用来存储指向下一条指令的地址。
  • 在创建线程的时候,创建相应的程序计数器。
  • 执行本地native方法时,程序计数器的值为undefined。
  • 是一块比较小的内存空间,是唯一一个在JVM规范中没有规定OutOfMemoryError的内存区域。

虚拟机栈

  • 栈是由一系列帧(Frame)组成(因此Java栈也叫作帧栈),是线程私有的。
  • 帧是用来保存一个方法的局部变量、操作数栈(java没有寄存器,所有的参数传递使用操作数栈)、常量池指针、动态链接、方法返回值等。
  • 每一次方法调用创建一个帧并压栈,退出方法的时候,修改栈顶指针就可以把栈帧中的内容销毁。

栈的优点:存取速度比堆快,仅次于程序计数器。
栈的缺点:存在栈中的数据太小,生存期是在编译期决定的,缺乏灵活性。
StackOverflowError异常:当线程请求的栈深度大于虚拟机所允许的深度;
OutOfMemoryError异常:如果栈的扩展时无法申请到足够的内存。

本地方法栈

在JVM中用来支持native方法执行的栈

用来存放应用系统创建的对象和数组,所有线程共享堆。是内存最大的一块区域,也是GC主要区域

方法区

方法区是所有线程共享的,用来保存装载的类的结构信息。

理解

运行时数据区,也就是下图这部分,它是在类加载类加载完成后的阶段

当通过前面的:类的加载 --> 验证 --> 准备 --> 解析 --> 初始化,这几个阶段完成后,就会用到执行引擎对我们的类进行使用,同时执行引擎将会使用到运行时数据区

https://www.mamq.top/wp-content/uploads/2022/10/42eab7a6999400aaf897cf0767471adb.png

比如大厨做饭,我们把大厨后面的东西(切好的菜,刀,调料),比作是运行时数据区。而厨师可以类比于执行引擎,将通过准备的东西制作成精美的菜品

https://www.mamq.top/wp-content/uploads/2022/10/b563b0aba573cc74d7b1e95be328c713.png

总结

  • 线程私有结构:程序计数器、虚拟机栈、本地方法栈
  • 每个虚拟机栈由具体的栈帧组成,在栈帧的动态链接中,保存至对方法的引用
  • 方法区在 JDK7 之前,使用永久代实现,在 JDK8 之后,使用元空间实现
  • Minor GC 针对于新生区,Major GC 针对于老年区,Full GC 针对于整个堆空间和方法区
赞(0) 打赏

评论 抢沙发