10|对象模型:JVM对象的内部机制和存在方式是怎样的?
JVM 对象基础协议
Java 对象的大小
- 深入了解
- 翻译
- 解释
- 总结
JVM对象模型和OOP-Klass模型是Java虚拟机中对象存储和多态实现的重要基础。文章首先介绍了Java对象的内部机制,包括对象头、实例数据和对齐区的结构,以及CPU对数据读取方式对JVM对象存储的影响。随后,深入探讨了OOP-Klass模型,解释了oop和Klass的作用,以及函数表在实现多态性方面的重要性。通过对JVM对象存储方式和多态实现的分析,读者可以更全面地了解JVM对象的内部机制和存在方式。此外,文章还涉及了JVM层的数据类型和Java对象的大小设置,为后续的性能优化提供了理论基础。通过本文的学习,读者能够深入了解JVM的对象模型和数据类型,为进一步探索Java虚拟机的内部机制打下坚实基础。
《云时代的 JVM 原理与实战》,新⼈⾸单¥59
全部留言(7)
- 最新
- 精选
- Nicopublic 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归属地:江苏