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

10|对象模型:JVM对象的内部机制和存在方式是怎样的?

你好,我是康杨。
这节课,我们一起来分析下微观环境下的 JVM“分子”——对象。我们会先从 Everything  is  object 中的 object 讲起,通过协议、模型、应用三部曲带你重新认识 JVM 中的对象。
对象是我们使用 Java 的基础,是所有方法和数据的载体,也是我们和 Java 世界交互的媒介,区别于以往的 C、C++ 语言,即使我们实现一个最简单的“Hello World” 程序,也需要先创建一个 Java 对象。那这个我们再熟悉不过的对象,在 JVM 中是以怎样的形态存在的?又是如何影响到我们的日常编码和调优的?带着这些问题,我们一起来开启 JVM 对象的探索之旅。

JVM 对象基础协议

Java 对象的大小

首先请你思考一个问题:一个 Java 对象有多大?你可能下意识地会觉得一个 Java 对象的大小没法评估,这取决于它管理了多少属性,而 JVM 并没有限制一个对象所管理的属性的数量和大小。但其实一个 Java 对象的大小在 JVM 中是有一个要求的,那就是 Java 对象的大小必须是 8 字节的整数倍。
JVM 为什么这么要求?又是如何做到的呢?这就涉及到了 Java 对象的基础协议。Java 对象协议是 JVM 对 Java 对象在 JVM 中如何存储的规定,协议中规定,在 JVM 中对象由三个部分构成,分别是对象头、实例数据、对齐区。
确认放弃笔记?
放弃后所记笔记将不保留。
新功能上线,你的历史笔记已初始化为私密笔记,是否一键批量公开?
批量公开的笔记不会为你同步至部落
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
  • 深入了解
  • 翻译
    • 英语
    • 中文简体
    • 中文繁体
    • 法语
    • 德语
    • 日语
    • 韩语
    • 俄语
    • 西班牙语
    • 阿拉伯语
  • 解释
  • 总结

JVM对象模型和OOP-Klass模型是Java虚拟机中对象存储和多态实现的重要基础。文章首先介绍了Java对象的内部机制,包括对象头、实例数据和对齐区的结构,以及CPU对数据读取方式对JVM对象存储的影响。随后,深入探讨了OOP-Klass模型,解释了oop和Klass的作用,以及函数表在实现多态性方面的重要性。通过对JVM对象存储方式和多态实现的分析,读者可以更全面地了解JVM对象的内部机制和存在方式。此外,文章还涉及了JVM层的数据类型和Java对象的大小设置,为后续的性能优化提供了理论基础。通过本文的学习,读者能够深入了解JVM的对象模型和数据类型,为进一步探索Java虚拟机的内部机制打下坚实基础。

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

全部留言(7)

  • 最新
  • 精选
  • Nico
    public class Main { public static void main(String[] args) { Book book = new Book(); Book colorBook = new ColorBook(); book.print(); colorBook.print(); } } 针对这段代码的主要字节码如下: Code: stack=2, locals=3, args_size=1 0: new #2 // class com/minis/jvm/Book 3: dup 4: invokespecial #3 // Method com/minis/jvm/Book."<init>":()V 7: astore_1 8: new #4 // class com/minis/jvm/ColorBook 11: dup 12: invokespecial #5 // Method com/minis/jvm/ColorBook."<init>":()V 15: astore_2 16: aload_1 17: invokevirtual #6 // Method com/minis/jvm/Book.print:()V 20: aload_2 21: invokevirtual #6 // Method com/minis/jvm/Book.print:()V 24: return 之前看JVM类加载阶段时说 “解析” 在某些情况下可以在初始化阶段之后开始,这是为了支持 Java 语言的运行时绑定,从这个字节码上看 ColorBook.print 执行的是 Book.print,那这个初始化阶段之后,是如何把 Book.print 换成了 ColorBook.print,这一段一直有点模糊,辛苦老师空了帮忙解答下,感谢!

    作者回复: 在 Java 中,当我们调用一个方法的时候,JVM 会根据这个方法在代码中的声明类型在类的方法表中查找对应的方法。这就是 `invokevirtual` 字节码指令所要做的事情。例如,在你的代码中,`colorBook.print()` 这个调用,虽然在字节码中看起来是要调用 `Book.print`,但实际上 JVM 会在运行时刻决定具体执行哪个方法。这是怎么做到的呢?我们知道,在 Java 中,方法可以被子类重写。所以,当 JVM 看到 `invokevirtual` 指令时,它会首先查看栈顶的对象引用,然后再根据这个引用具体的类型,去类的方法表中查找对应的方法。如果找到了就调用,如果没有找到就会向上(父类)查找,直到找到为止。所以说,`ColorBook.print()` 这个调用,虽然在字节码中表示的是 `Book.print`,但在运行时,JVM 会根据 `colorBook` 对象的实际类型 (`ColorBook`),最终会找到并执行 `ColorBook.print` 方法。如果 `ColorBook` 类没有重写 `print` 方法,那么它会去执行 `Book.print` 方法。这就是 Java 的动态绑定和运行时多态的一部分,也是面向对象编程的重要特性之一。

    2023-09-11归属地:浙江
    4
  • 浩仔是程序员
    老师,你好!对象头的mark world有些不理解,在图中展示的意思一个对象在不同的状态存储不同的状态吗?比如在重量级锁的时候就没有储存hashcode?

    作者回复: 当对象进入重量级锁状态的时候,其对象头(Mark Word部分)是不再直接存储哈希码的。但这并不影响我们获取对象的哈希码,因为JVM有其自己的处理机制。之后,对象头就不再存储hashcode。当需要hashcode的时候,会去Monitor中查找之前储存的hashcode。存储hashcode的操作发生在阻塞前,所以即使阻塞后对象头的信息被覆盖,hashcode依然可以从Monitor中找到。

    2023-09-26归属地:广东
    2
  • peter
    请教老师两个问题: Q1:CPU读的“字”是四个字节吗? Q2:klass是方法的内存地址吗?

    作者回复: A1: CPU读取数据的单位根据机器体系结构和具体CPU的设计来决定,通常是以"字(word)"作为单位。"字"是数据总线一次能够传输的二进制代码的位数,这取决于CPU的内部数据总线的宽度。对于32位的CPU来说,一个字就是32位即4个字节,64位CPU中,一个字是64位即8个字节。举例来说,对于一个字长为32位的机器,我们通常说一次读写操作可以读写4个字节,这是因为32位等于4个字节(每个字节为8位)。然而,还需要根据实际情况来确定,*"字"* 这个术语在不同的环境和上下文中可能会有所不同,有时候也可能指单个字符(在字符编码中),因此最好根据特定环境和具体文档来确定 *"字"* 的具体大小。 A2:不是,klass不是方法的内存地址,而是代表Java类在JVM内部的表示。

    2023-09-11归属地:北京
    1
  • ^_^
    方法表是在准备阶段还是解析阶段创建的呢?

    作者回复: JVM的方法表是在类加载的解析阶段创建的

    2023-09-11归属地:北京
    1
  • 静心
    也不知道是我的基本不够,还是理解有点差。总感觉没太完全理解。比如,Markword中几种锁的数据,是每个对象都会预留各种锁的数据?还是会根据情况切换不同的锁数据存储结构?
    2024-02-04归属地:山西
  • 等风来🎧
    最后一张图,对象实例数据和类指针的位置是不是画反了?类指针不该再对象头里面吗?老师都用英文表示吧比如Book 的 Klass 指针,而不是 Book 的类指针。因为 java 的 Class 和 Klass'很容易让人混淆。
    2024-01-08归属地:江苏
  • C.
    JVM 的对象模型:对象、类、类加载器和类型信息。 JVM 层的数据类型:基本数据类型、引用类型、数组类型、接口类型、枚举类型。 特殊的数据类型和机制:泛型、注解、反射。
    2023-09-11归属地:江苏
收起评论
显示
设置
留言
7
收藏
沉浸
阅读
分享
手机端
快捷键
回顶部