zl程序教程

您现在的位置是:首页 >  Java

当前栏目

Java对象内部结构

2023-04-18 12:53:49 时间

Java对象内部结构分析

(在压缩指针情况下分析)

对象头

  1. 对象头占用12个字节,存储内容包括对象标记(markOop)和类元信息(klassOop)。
  2. 对象标记存储对象本身运行时的数据,如哈希码、GC标记、锁信息、线程关联信息等,这部分数据在64位JVM上占用8个字节,成为"Mark Word"。
  3. 为了存储更多的状态信息,对象标记的存储格式是非固定的(具体与JVM的实现有关)。类元信息存储的是对象指向它的类元数据(即Klass)的首地址,占用4个字节.

实例数据

存储本类对象的实例成员变量和所有可见的父类成员变量。如Interger的实例成员只有一个private int value ,占用4个字节,所以加上对象头为16个字节, 需要注意计算子类占用时,需要加上父类的所有字段

对齐填充

对象的存储空间分配单位是8个字节,如果一个占用大小16个字节的对象,增加一个成员变量byte类型,此时需要占用17个字节,但是也会分配24个字节进行对齐填充

实战(评估对象占用字节)

class RefObjectDemo {
	//对象头最小占用空间12个字节
	//byte 基础类型占用 1个字节
	byte b;
	//short 基础类型占用 2个字节
	short s;
	//int 基础类型占用 4个字节
	int i;
	//long 基础类型占用 8个字节
	long l;
	//float 基础类型占用 4个字节
	float f;
	//duuble 基础类型占用 8个字节
	double d;
	//boolean 基础类型占用 1个字节
	boolean b1;
	//char 基础类型占用 2个字节
	char c;
	//引用变量类型占用是4个字节
	Object o;
	//double 类型占用8个字节,但此处是数组引用变量 所以占用4个字节
	//注意并不计算 new double[1000]
	//这个数组引用的是double[]类型,指向实际分配的数组空间首地址
	//在new对象时,已经实际分配空间
	double[] d=new double[1000];
}
//12+1+2+4+8+4+8+1+2+4+8 = 54字节
//取8的倍数为56个字节
//对象填充 2个字节