java的对象模型以及对象的存储方式

转载1
转载2

java的对象模型以及对象的存储方式

1、java对象保存在堆内存中。在内存中,一个java对象包含三部分:对象头、实例数据和对其填充。其中对象头包含锁状态标志、线程持有的锁等标志。
2、对象的实例(instantOopDesc)保存在堆上,对象的元数据(instantKlass)保存在方法区,对象的引用保存在栈上。

3、方法区用于存储虚拟机加载的类信息、常量、静态变量、即时编译器编译后的代码等数据。

4、举例

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);
}

存储结构如下:

在这里插入图片描述

总结
每一个java类,在被JVM加载的时候,JVM会给这个类创建一个instanceKlass,保存在方法区,用来在JVM层表示该java类。当我们在java代码中,使用new创建一个对象的时候,JVM会创建一个instanceOopDesc对象,这个对象包含了对象头和实例数据。对象头中有一些运行时数据,其中就包含了和多线程相关的锁信息。元数据其实维护的是指针,指向的是对象所属的类的instanceKlass。

对象结构
对象头
HotSpot虚拟机的对象头包括两部分信息:
markword
第一部分markword,用于存储对象自身的运行时数据,如哈希码(HashCode)、GC分代年龄、锁状态标志、线程持有的锁、偏向锁ID、偏向时间戳等,这部分数据的长度在32位和64位的虚拟机(未开启压缩指针)中分别为32bit和4bit。
kclass
对象头的另外一部分是kclass类型指针,即对象指向它的类元数据的指针,虚拟机通过这个指针来确定它的对象是哪个类的实例。类被加载到内存时,就被封装成了klass,klass包含类的元数据信息,像类的方法、常量池等信息都是存在klass里的,你可以认为是java里面的java.lang.Class对象,记录了类的全部信息。
数组长度(只有数组对象有)
如果对象是一个数组,那么在对象头中必须有一块数据用来记录数组长度
在这里插入图片描述
Mark Word:
在这里插入图片描述
实例数据
实例数据部分是对象真正存储的有效信息,也是在程序代码中所定义的各种类型的字段内容,无论是从父类继承下来的,还是在子类中定义的,都需要记录起来。
对齐填充
第三部分对齐填充并不是必然存在的,也没有特别的含义,它仅仅起着占位符的作用。由于HotSpot VM的自动内存管理系统要求对象起始地址必须是8字节的整数倍,换句话说,就是对象的大小必须是8字节的整数倍。而对象头部分正好是8字节的倍数(1倍或者2倍),因此,当对象实例数据部分没有对齐时,就需要通过对齐填充来补全。

对象大小计算
要点

  1. 在32位系统下,存放Class指针的空间大小是4字节,MarkWord是4字节,对象头为8字节。
  2. 在64位系统下,存放Class指针的空间大小是8字节,MarkWord是8字节,对象头为16字节。
  3. 64位开启指针压缩的情况下,存放Class指针的空间大小是4字节,MarkWord是8字节,对象头为12字节。 数组长度4字节+数组对象头8字节(对象引用4字节(未开启指针压缩的64位为8字节)+数组markword为4字节(64位未开启指针压缩的为8字节))+对齐4=16字节。
  4. 静态属性不算在对象大小内。
  • 2
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java内存模型Java Memory Model,JMM)定义了Java程序在多线程环境下的内存访问规则。它规定了线程如何和主内存、本地内存以及其他线程进行通信。 JVM内存模型是指Java虚拟机(Java Virtual Machine,JVM)在执行Java程序时的内存布局和管理方式。JVM内存模型包括了堆内存、栈内存、方法区、直接内存等。 在Java内存模型,主要有以下几个概念: 1. 主内存:所有线程共享的内存区域,包含了实例字段、静态字段以及数组元素。 2. 工作内存:每个线程独立的内存区域,包含了该线程使用的变量副本或者缓存。 3. 内存间的交互操作:线程之间通过读写主内存来进行通信。 4. 原子性、可见性和有序性:JMM保证了原子性(对基本类型的读写操作具有原子性)、可见性(一个线程对主内存的修改对其他线程是可见的)和有序性(在一个线程,按照程序顺序执行)。 JVM内存模型主要包括以下几个部分: 1. 堆内存:用于存储对象实例,由垃圾回收器进行管理。 2. 栈内存:用于存储方法的局部变量和方法调用的信息。每个线程都有自己的栈内存。 3. 方法区:用于存储类的信息、常量、静态变量等。 4. 直接内存:在堆外分配内存,不受JVM管理,由操作系统进行管理。 需要注意的是,JVM内存模型是具体实现的一种规范,可以根据不同的JVM厂商进行优化和调整。而Java内存模型Java语言规范定义的多线程内存访问规则,对于不同的JVM实现都是一样的。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值