初步了解Java对象布局

背景

最近在学习JAVA对象布局的一些底层实现原理,在这边做了总结归纳,方便大家学习。

CAS的最终实现(指令)

// cmpxchg = cas修改变量值 
lock cmpxchg

JOL(java object layout) Java对象布局

常见对象内存布局:

Object、Integer、boolean(16 bytes)

String、Long、Double(24 bytes)

整型:

其中byte、short、int、long都是表示整数的,只不过他们的取值范围不一样

可以看到byte和short的取值范围比较小,而long的取值范围太大,占用的空间多,基本上int可以满足我们的日常的计算了,而且int也是使用的最多的整型类型了。

在通常情况下,如果JAVA中出现了一个整数数字比如35,那么这个数字就是int型的,如果我们希望它是byte型的,可以在数据后加上大写的 B:35B,表示它是byte型的。

同样的35S表示short型,35L表示long型的,表示int我们可以什么都不用加,但是如果要表示long型的,就一定要在数据后面加“L”。

浮点型:

  • float和double是表示浮点型的数据类型,他们之间的区别在于他们的精确度不同
  • float 3.402823e+38 ~ 1.401298e-45(e+38表示是乘以10的38次方,同样,e-45表示乘以10的负45次方)占用4个字节
  • double 1.797693e+308~ 4.9000000e-324 占用8个字节

double型比float型存储范围更大,精度更高,所以通常的浮点型的数据在不声明的情况下都是double型的,如果要表示一个数据是float型的,可以在数据后面加上“F”。

浮点型的数据是不能完全精确的,所以有的时候在计算的时候可能会在小数点最后几位出现浮动,这是正常的。

boolean型(布尔型):

这个类型只有两个值,true和false(真和非真)

  • boolean t = true;
  • boolean f = false;

char型(文本型) :

用于存放字符的数据类型,占用2个字节,采用unicode编码,它的前128字节编码与ASCII兼容

字符的存储范围在\u0000~\uFFFF,在定义字符型的数据时候要注意加’ ',比如 '1’表示字符’1’而不是数值1,

char c = ’ 1 ';

我们试着输出c看看,System.out.println©;结果就是1,而如果我们这样输出呢System.out.println(c+0);

结果却变成了49。

对象内存布局

对象包含三个部分,对象头、实例数据、对齐填充数据。

对齐填充字节是为了满足Java对象大小必须满足是8字节的倍数这一条件设计的,为了对象而填充一些无用字节实例数据就是在初始化数据时设定的属性和状态的内容。

对象头,存放了一些对象本身的运行时信息包含两部分 : Mark Word , Class Pointer,相较于实例数据,对象头属于一些额外的存储开销,所以它被设计得极小来提高效率。Class Pointer就是一个指针,指向了当前对象类型所在方法区中的类型数据,Mark Word存储了很多和当前对象运行时状态有关的数据。

image.png

查看对象内存布局

pom中引用依赖:

<dependency>
    <groupId>org.openjdk.jol</groupId>
    <artifactId>jol-core</artifactId>
    <version>0.9</version>
</dependency>

demo:

public class TestClassLayout {

    /**
     * 打印对象内存布局
     */
    @Test
    public void test1() {
//        Object o = new Object();
//        Long o = 0L;
//        Double o = 0D;
        String o = "0";

        System.out.println(ClassLayout.parseInstance(o).toPrintable());
    }
}

输出结果:

java.lang.String object internals:
 OFFSET  SIZE     TYPE DESCRIPTION                               VALUE
      0     4          (object header)                           01 00 00 00 (00000001 00000000 00000000 00000000) (1)
      4     4          (object header)                           00 00 00 00 (00000000 00000000 00000000 00000000) (0)
      8     4          (object header)                           da 02 00 f8 (11011010 00000010 00000000 11111000) (-134216998)
     12     4   char[] String.value                              [0]
     16     4      int String.hash                               0
     20     4          (loss due to the next object alignment)
Instance size: 24 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total

锁的信息

锁的信息是放在在对象的markword中,我们可以看下具体示例代码:

public class TestClassLayout {

    /**
     * 打印对象内存布局
     */
    @Test
    public void test1() {
        Object o = new Object();
        System.out.println(ClassLayout.parseInstance(o).toPrintable());

        synchronized (o) {
            System.out.println(ClassLayout.parseInstance(o).toPrintable());
        }
    }
}

输出结果:

java.lang.Object object internals:
 OFFSET  SIZE   TYPE DESCRIPTION                               VALUE
      0     4        (object header)                           01 00 00 00 (00000001 00000000 00000000 00000000) (1)
      4     4        (object header)                           00 00 00 00 (00000000 00000000 00000000 00000000) (0)
      8     4        (object header)                           e5 01 00 f8 (11100101 00000001 00000000 11111000) (-134217243)
     12     4        (loss due to the next object alignment)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total

java.lang.Object object internals:
 OFFSET  SIZE   TYPE DESCRIPTION                               VALUE
      0     4        (object header)                           20 eb 96 08 (00100000 11101011 10010110 00001000) (144108320)
      4     4        (object header)                           00 70 00 00 (00000000 01110000 00000000 00000000) (28672)
      8     4        (object header)                           e5 01 00 f8 (11100101 00000001 00000000 11111000) (-134217243)
     12     4        (loss due to the next object alignment)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total


Process finished with exit code 0

image.png

THE END.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值