云时代的 JVM 原理与实战
康杨
京东资深架构师
3111 人已学习
新⼈⾸单¥59
登录后,你可以任选4讲全文学习
课程目录
已完结/共 39 讲
云时代的 JVM 原理与实战
15
15
1.0x
00:00/00:00
登录|注册

03|工作台:JVM运行时数据区的内部机制是怎样的?

你好,我是康杨。今天这节课我们来聊聊 JVM 的运行时数据区。了解 JVM 的方法执行内存模型,掌握更多提升 Java 程序性能的技巧。
运行时数据区(Runtime Data Area)用于提供 JVM 运行时的内存空间的数据。以线程的视角出发,这个区域又分成线程共享区域和线程独享区域。
线程的独享区域由程序计数器、虚拟机栈(VM 栈)和本地方法栈构成,它们的使用寿命与线程的运行时间相同,因此可以有效避免垃圾回收的麻烦,并且可以根据线程的不断发展进行相应的调整。
线程共享区域包括堆和方法区,方法区用于存储类的结构信息,堆用于存储对象实例等。这节课我们将聚焦在线程独享区域,方法区和堆的介绍我将在类加载器和 GC 的部分为你详细介绍。

程序计数器

程序计数器属于线程私有资源,每个线程都有一个唯一的属于自己的程序计数器,指定线程所执行的字节码指令的行号。执行 Java 方法时,这个地方记录的是线程正在执行的字节码的指令地址,如果执行本地方法,这个地方的值为空。

应用场景

程序计数器是字节码解释器的核心,它可以根据程序计数器的数值,为下一步的字节码操作提供准确的指引,从而使程序更加高效地完成任务。
在实际的流程控制中,循环、跳转、分支等基础功能的运作也依赖于程序计数器。在涉及多线程的环境下,程序计数器保存了当前线程运行的位置,这样在线程再次被调用时,可以了解到这个线程之前运行到了什么地方。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

JVM运行时数据区包括线程独享区域和线程共享区域,其中线程独享区域包括程序计数器、虚拟机栈和本地方法栈,而线程共享区域包括堆和方法区。操作数栈是Java虚拟机的工作空间,通过压栈和出栈方式实现对数据的快速访问。动态链接在程序运行时通过链接到运行时常量池的引用,实现方法调用的动态链接。返回地址用于方法执行结束后返回到方法被调用的位置,对于正常结束,返回地址保存在栈帧中,而对于异常结束,则需要通过异常处理器表获取。本地方法栈主要负责执行由非Java语言编写的Native方法。通过学习这些内容,读者可以更深入地理解JVM运行时数据区的实现原理和优化策略,以及提升程序性能的技巧。

仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《云时代的 JVM 原理与实战》
新⼈⾸单¥59
立即购买
登录 后留言

全部留言(9)

  • 最新
  • 精选
  • 记得晚睡
    好难啊😭😭😭

    作者回复: 坚持学习就会觉得越来越简单,加油💪🏻💪🏻💪🏻💪🏻

    2023-09-20归属地:北京
    2
  • Levi
    老师请教一个问题,Slot只保存局部变量的值吗,比如a=2,slot中保存的是2这个数据值,那a这个变量被保存在哪里呢?

    作者回复: 在JVM中,Slot(插槽)是用来存储局部变量的数据结构。当一个方法被调用时,JVM会在栈帧中为这个方法分配一个局部变量表,以存放该方法的所有局部变量。而每一个局部变量,在这个局部变量表中就占用一个或者多个Slot。所以,对于你提到的情况,变量a的值2会被保存在Slot中,而变量a本身,也就是变量名,不会存储在Slot中。在Java中,变量名只是在编译阶段存在,用来帮助开发者理解和操作数据。一旦编译结束,变量名就不再需要了,因为JVM在运行时,只关心数据,而不关心这个数据是通过什么变量名得到的。所以说,变量a本身会在编译结束后被丢弃,只有它的值2会被保存在Slot中。

    2023-08-27归属地:北京
    2
  • funnyx
    请问老师,有没有什么方法在jvm运行时,向其中添加class文件让其加载。

    作者回复: Java提供了一种机制,叫做动态类加载,可以在JVM运行时将新的Java类(.class文件)添加到正在运行的应用程序中

    2023-09-09归属地:浙江
    1
  • Johar
    程序计数器是记录程序正在执行字节码的指令地址,但是执行本地方法,为空。 请问一下老师,执行本地方,程序计数器记录的指令地址为空,在cpu时间片切换时,怎么再次恢复本地方法的执行上下文?

    作者回复: 当进行CPU时间片切换时,Java虚拟机需要恢复本地方法的执行上下文,确保从切换中恢复过来后能够继续执行本地方法。为了实现上下文的恢复,Java虚拟机会利用操作系统的调度机制,将本地方法的执行状态保存在与本地方法相对应的线程栈帧中。当线程被重新调度执行时,会从保存的栈帧中恢复本地方法的执行上下文,继续执行本地方法。 需要注意的是,由于本地方法的执行过程是在本地库中进行的,具体的上下文恢复过程是与操作系统和本地库相关的,并且可能因不同的操作系统或本地库而有所不同。 Java虚拟机只负责协助操作系统进行本地方法与Java线程的切换,并确保上下文的正确恢复。

    2023-08-25归属地:重庆
    1
  • Calvin
    大佬好: 请问下“运行时常量池”包括哪些东西,在运行时数据区的哪个位呢置(本文好像没说?)? 与“字符串常量池”有什么区别,为什么还需要特意再分出来多一个常量池呢?

    作者回复: 我在后面几节马上就好讲这个了,应该下周就能看到了,你可以先看下,有问题我们随时沟通

    2023-08-25归属地:广东
  • Geek1254
    看了两节,感觉讲的东西太浅,不适合工作多年的老鸟。要硬干货
    2023-09-15归属地:北京
    4
  • 临风
    1、JVM 中方法执行的内存模型对应的是运行时数据区的那个区域? 运行时数据区包括程序计数器、虚拟机栈、本地方法栈、方法区、堆区。一个执行方法对应虚拟机栈的一个栈帧,栈帧会保存局部变量表、操作数栈、动态链接、返回地址等。 2、这节课你学到了哪些提升程序性能的技巧? 一是不要定义多余的变量;二是方法不要过长。这两个都是编程规范要求的,之前以为仅仅只是为了可读性,还是为了避免局部变量表空间的浪费。
    2023-08-27归属地:广东
    1
  • Geek_0e0559
    针对每个栈帧,我们还需要提供一个引用,以此在运行时常量池内可以识别出对应的方法,且在方法被调用的过程中能实现动态链接。-- 这句话没看明白
    2024-02-26归属地:黑龙江
  • peter
    请教老师几个问题: Q1:动态链接部分的methodA方法的疑问: --- 此函数没有参数,为什么args_size是1? --- 此函数没有局部变量,为什么locals是1? --- stack=2是什么意思? Q2:sun hotpot将两个栈合并,虚拟机栈是执行Java代码的,那么本地方法还能执行C或C++代码吗? Q3:本课所说的“动态链接”,主要是指“动态绑定”,即多态,不是指“动态链接库”一类的内容,对吗? Q4:Java程序可以使用C或C++的DLL吗?
    2023-08-26归属地:河北
    1
收起评论
显示
设置
留言
9
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部