JVM源码分析:Java对象模型(OOP-Klass模型),Java对象在JVM中的表现形式

本文探讨了Java对象在JVM中的表示形式,特别是Hotspot JVM中的OOP-Klass模型。OOP(Ordinary Object Pointer)表示对象实例信息,而Klass则包含元数据和方法信息。通过这种分离设计,避免了每个对象包含虚函数表。在Hotspot中,InstanceKlass描述Java类信息,InstanceOopDesc表示普通Java对象,二者分别位于元空间和堆中。文章还介绍了对象的内存布局,包括对象头和数据部分,以及访问方式(句柄访问和直接指针访问)的优缺点。
摘要由CSDN通过智能技术生成

jvm环境:openJdk15_20的hotspot

一、问题背景

当我们在java程序中,使用new创建一个对象时,是否考虑过或者知道这个对象在JVM中是如何表示的?它占用的内存大小是多少?

class A {
   
	int a;
}
public static void main(String[] args) {
   
	A a = new A();
}

二、Java对象模型-OOP-Klass

在JVM中,Hotspot并没有将Java对象映射成C++对象,而是实现了Java的对象模型(OOP-Klass),JVM不希望每个对象中都包含一份虚函数表(Why???待探究)。
那么为何要设计这样一个一分为二的对象模型呢?这是因为 HotSopt JVM 的设计者不想让每个对象中都含有一个 vtable(虚函数表),所以就把对象模型拆成 klass 和 oop,其中 oop 中不含有任何虚函数,而 klass 就含有虚函数表,可以进行 method dispatch。这个模型其实是参照的 Strongtalk VM 底层的对象模型。

下面解释下OOP-Kclass模型的定义:

  • OOP 英文全程是Ordinary Object Pointe,即普通对象指针,看起来像个指针实际上是藏在指针里的对象,表示对象的实例信息。
  • Klass 元数据和方法信息,用来描述 Java。是Java类的在C++中的表示形式,用来描述Java类的信息。

当加载一个Class时,会创建一个InstanceKlass对象,实例化的对象则对应InstanceOopDesc,instanceOopDesc继承自oopDesc,用于表示普通的Java对象,每次new一个Java对象就会创建一个新的instanceOopDesc实例,其中InstanceKlass存放在元空间,InstanceOopDesc存放在堆中。

由于 Java 8 引入了 Metaspace,OpenJDK 1.8 里对象模型的实现与 1.7 有很大的不同。原先存于 PermGen 的数据都移至 Metaspace,因此它们的 C++ 类型都继承于 MetaspaceObj 类(定义见 vm/memory/allocation.hpp),表示元空间的数据。

如下一个对象组成部分所示,InstanceOopDesc是对象的头部,对象的数据部分紧跟其后。
在这里插入图片描述
多个对象的ModelA和ModelB的定义如下:

class Model
{
   
    public static int a = 1;
    public int b;
    public Model(int b) {
   
        this.b = b;
    }
}
public static void main(String[] args) {
   
    int c = 10;
    Model modelA = new Model(2);
    Model modelB = new Model(3);
}

如下是分配情况:
在这里插入图片描述

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值