Java对象布局工具

2020-03-20  本文已影响0人  随风遣入夜

何为对象布局?这个工具能够帮到我们什么呢?


可以不看

或许你经常有这样的疑惑?一个对象究竟占了多少的物理空间呢?这个问题可能对于其他高级语言来说,可能会很简单,因为会直接面临物理内存空间的使用问题,但是,作为Java这种特性的语言,就是将这种问题在jvm里处理了,统一的由jvm去管理分配每个时间片上的物理内存占用或者清退,所以平时大多数时候我们关注不到这些,而我们常常要做的就是new一个新对象,剩下的 交给jvm了,我们埋头CRUD即可,这样从开发效率上来说是有好处的,但是对于我们自身,对于计算机的认识来讲,相比于其他语言,是有些先天不足,所以我们要自己探究我们上面的问题:你new出来的对象到底占了多少物理空间?
好的,假设你明白了new出来的对象占了多少物理空间,那么下次你再去new一个对象的时候,你可能会想到、预估到当前的场景你消耗了多少物理内存资源,且不说IO问题,这时候对于我们自身的编码可能会起到一些小小的影响,虽然有jvm帮我们,但是我们自己也要帮自己,写出更快更节省资源的代码。


OK我的论述就到这里了,下面是介绍

Java对象布局工具

<!--添加这个工具的依赖-->
<dependency>
    <groupId>org.openjdk.jol</groupId>
    <artifactId>jol-core</artifactId>
    <version>0.9</version>
</dependency>

了解一下new出来的对象的内存模型(借用下别人的图)


new出来新对象的内存组成

对象三部分:头 实例数据(对象内容) 补齐部分

现在我们创建一个类Apple 先不给添加任何显示的属性 用对象布局工具打印一下,看看

public class T02 {

    public static void main(String[] args) {

        Apple apple = new Apple();
        //使用对象模型工具将对象以表格字符串的形式打印出来
        ptn(ClassLayout.parseInstance(apple).toPrintable());
    }

    public static void ptn(String msg){
        System.out.println(msg);
        System.out.println("======割=====");
    }
}
/***********结果************/

//开始位置 大小   类型    描述                                                值
 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)                           43 c1 00 f8 (01000011 11000001 00000000 11111000) (-134168253)
     12     4        (loss due to the next object alignment)
Instance size: 16 bytes
Space losses: 0 bytes internal + 4 bytes external = 4 bytes total
上面结果的截图

好的下面解释一下

上面我们已经把对象模型分为三部分了,头、实例数据(对象内容)、对象补齐
可是大概看看表格 会发现没有只有三行头部数据 和 一行补齐数据
用一共16byte就表述了刚 new 出来的Apple对象
没看到对象内容,为什么呢?是不是因为我们的Apple对象确实没有任何属性的原因呢?
先不解答,我们用这个工具来自己论证这个猜想。

now,给Apple两个字段,int id、String code;
再用对象布局工具打印下,Apple类我就不放了 就是加两个字段 直接看打印结果

 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)                           43 c1 00 f8 (01000011 11000001 00000000 11111000) (-134168253)
     12     4                int Apple.id                                  0
     16     4   java.lang.String Apple.code                                null
     20     4                    (loss due to the next object alignment)
Instance size: 24 bytes
上面结果的截图
现在对比第一次的结果我们可以清楚的看到,出现新添加的两个属性,即对象内容各占4个byte
最后补位4byte 共24byte
这个结论印证了上面我们的猜想,也就是说
对象的内容决定了对象的大小,这也是完全符合我们客观世界的规律的。这应该也算OO的一个思想体现吧。

OK 关于这个工具还有很多好玩的 等着我们去探索,噢差点忘了一个比较重要的内容,关于指针压缩的概念,我们以上的测试结果都是基于压缩后的结果 一般HotSpot虚拟机默认开启压缩。

上一篇下一篇

猜你喜欢

热点阅读