前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >初步了解Java对象布局

初步了解Java对象布局

作者头像
iiopsd
发布2023-10-17 14:23:26
1360
发布2023-10-17 14:23:26
举报
文章被收录于专栏:iiopsd技术专栏iiopsd技术专栏

背景

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

CAS的最终实现(指令)

代码语言:javascript
复制
// 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
image.png

查看对象内存布局

pom中引用依赖:

代码语言:javascript
复制
<dependency>
    <groupId>org.openjdk.jol</groupId>
    <artifactId>jol-core</artifactId>
    <version>0.9</version>
</dependency>

demo:

代码语言:javascript
复制
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());
    }
}

输出结果:

代码语言:javascript
复制
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中,我们可以看下具体示例代码:

代码语言:javascript
复制
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());
        }
    }
}

输出结果:

代码语言:javascript
复制
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
image.png

THE END.

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
原始发表:2023-10-11,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 背景
  • CAS的最终实现(指令)
  • JOL(java object layout) Java对象布局
  • 对象内存布局
  • 查看对象内存布局
  • 锁的信息
  • THE END.
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档