热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

javaobject对象在heap中的结构是什么

javaobject对象在heap中的结构是什么,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来

java object对象在heap中的结构是什么,很多新手对此不是很清楚,为了帮助大家解决这个难题,下面小编将为大家详细讲解,有这方面需求的人可以来学习下,希望你能有所收获。      

简介

在之前的文章中,我们介绍了使用JOL这一神器来解析java类或者java实例在内存中占用的空间地址。


今天,我们会更进一步,剖析一下在之前文章中没有讲解到的更深层次的细节。一起来看看吧。

对象和其隐藏的秘密

java.lang.Object大家应该都很熟悉了,Object是java中一切对象的鼻祖。


接下来我们来对这个java对象的鼻祖进行一个详细的解剖分析,从而理解JVM的深层次的秘密。


工具当然是使用JOL:


@Slf4jpublic class JolUsage {
   @Test    public void useJol(){        log.info("{}", VM.current().details());  log.info("{}", ClassLayout.parseClass(Object.class).toPrintable());        log.info("{}", ClassLayout.parseInstance(new Object()).toPrintable());    }}


代码很简单,我们打印JVM的信息,Object class和一个新的Object实例的信息。


看下输出:

java object对象在heap中的结构是什么


从上面的结果我们知道,在64位的JVM中,一个Object实例是占用16个字节。


因为Object对象中并没有其他对象的引用,所以我们看到Object对象只有一个12字节的对象头。剩下的4个字节是填充位。


Object对象头

那么这12字节的对象头是做什么用的呢?


如果想要深入了解这12字节的对象头,当然是要去研读一下JVM的源码:src/share/vm/oops/markOop.hpp。


有兴趣的小伙伴可以去看看。如果没有兴趣,没关系,这里给大家一个张总结的图:

java object对象在heap中的结构是什么


javaObject对象的对象头大小根据你使用的是32位还是64位的虚拟机的不同,稍有变化。这里我们使用的是64位的虚拟机为例。


Object的对象头,分为两部分,第一部分是Mark Word,用来存储对象的运行时数据比如:hashcode,GC分代年龄,锁状态,持有锁信息,偏向锁的thread ID等等。


在64位的虚拟机中,Mark Word是64bits,如果是在32位的虚拟机中Mark Word是32bits。


第二部分就是Klass Word,Klass Word是一个类型指针,指向class的元数据,JVM通过Klass Word来判断该对象是哪个class的实例。


且慢!


有的小伙伴可能发现了问题,之前我们用JOL解析Object对象的时候,Object head大小是12字节,也就是96bits,这里怎么写的是128bits?

java object对象在heap中的结构是什么


没错,如果没有开启COOPs就是128bits,如果开启了COOPs,那么Klass Word的大小就从64bits降到了32bits。


还记得我们之前讲的COOPs吗?


COOPs就是压缩对象指针技术。


对象指针用来指向一个对象,表示对该对象的引用。通常来说在64位机子上面,一个指针占用64位,也就是8个字节。而在32位机子上面,一个指针占用32位,也就是4个字节。


实时上,在应用程序中,这种对象的指针是非常非常多的,从而导致如果同样一个程序,在32位机子上面运行和在64位机子上面运行占用的内存是完全不同的。64位机子内存使用可能是32位机子的1.5倍。


而压缩对象指针,就是指把64位的指针压缩到32位。


怎么压缩呢?64位机子的对象地址仍然是64位的。压缩过的32位存的只是相对于heap base address的位移。


我们使用64位的heap base地址+ 32位的地址位移量,就得到了实际的64位heap地址。


对象指针压缩在Java SE 6u23 默认开启。在此之前,可以使用-XX:+UseCompressedOops来开启。


数组对象头

java中有一个非常特别的对象叫做数组,数组的对象头和Object有什么区别吗?


我们用JOL再看一次:

log.info("{}",ClassLayout.parseClass(byte[].class).toPrintable());log.info("{}",ClassLayout.parseInstance("www.flydean.com".getBytes()).toPrintable());

上面的例子中我们分别解析了byte数组的class和byte数组的实例:


java object对象在heap中的结构是什么


看到区别了吗?我们发现数组的对象头是16字节,比普通对象的对象头多出了4个字节。这4个字节就是数组的长度。


整个对象的结构

好了,写到这里我们来总结一下,java对象的结构可以分为普通java对象和数组对象两种:


数组对象在对象头中多了一个4字节的长度字段。


大家看到最后的字节是padding填充字节,为什么要填充呢?


因为JVM是以8字节为单位进行对其的,如果不是8字节的整数倍,则需要补全。

更多精彩内容

1

看动画学算法之:排序-归并排序

2

计算机揭秘之:网络分类和性能分析

3

JVM详解之:运行时常量池

看完上述内容是否对您有帮助呢?如果还想对相关知识有进一步的了解或阅读更多相关文章,请关注编程笔记行业资讯频道,感谢您对编程笔记的支持。


推荐阅读
  • 标题: ... [详细]
  • 本文介绍了Python爬虫技术基础篇面向对象高级编程(中)中的多重继承概念。通过继承,子类可以扩展父类的功能。文章以动物类层次的设计为例,讨论了按照不同分类方式设计类层次的复杂性和多重继承的优势。最后给出了哺乳动物和鸟类的设计示例,以及能跑、能飞、宠物类和非宠物类的增加对类数量的影响。 ... [详细]
  • 本文整理了315道Python基础题目及答案,帮助读者检验学习成果。文章介绍了学习Python的途径、Python与其他编程语言的对比、解释型和编译型编程语言的简述、Python解释器的种类和特点、位和字节的关系、以及至少5个PEP8规范。对于想要检验自己学习成果的读者,这些题目将是一个不错的选择。请注意,答案在视频中,本文不提供答案。 ... [详细]
  • 精讲代理设计模式
    代理设计模式为其他对象提供一种代理以控制对这个对象的访问。代理模式实现原理代理模式主要包含三个角色,即抽象主题角色(Subject)、委托类角色(被代理角色ÿ ... [详细]
  • 初识java关于JDK、JRE、JVM 了解一下 ... [详细]
  • Java太阳系小游戏分析和源码详解
    本文介绍了一个基于Java的太阳系小游戏的分析和源码详解。通过对面向对象的知识的学习和实践,作者实现了太阳系各行星绕太阳转的效果。文章详细介绍了游戏的设计思路和源码结构,包括工具类、常量、图片加载、面板等。通过这个小游戏的制作,读者可以巩固和应用所学的知识,如类的继承、方法的重载与重写、多态和封装等。 ... [详细]
  • 本文介绍了C#中生成随机数的三种方法,并分析了其中存在的问题。首先介绍了使用Random类生成随机数的默认方法,但在高并发情况下可能会出现重复的情况。接着通过循环生成了一系列随机数,进一步突显了这个问题。文章指出,随机数生成在任何编程语言中都是必备的功能,但Random类生成的随机数并不可靠。最后,提出了需要寻找其他可靠的随机数生成方法的建议。 ... [详细]
  • 先看官方文档TheJavaTutorialshavebeenwrittenforJDK8.Examplesandpracticesdescribedinthispagedontta ... [详细]
  • MPLS VP恩 后门链路shamlink实验及配置步骤
    本文介绍了MPLS VP恩 后门链路shamlink的实验步骤及配置过程,包括拓扑、CE1、PE1、P1、P2、PE2和CE2的配置。详细讲解了shamlink实验的目的和操作步骤,帮助读者理解和实践该技术。 ... [详细]
  • 纠正网上的错误:自定义一个类叫java.lang.System/String的方法
    本文纠正了网上关于自定义一个类叫java.lang.System/String的错误答案,并详细解释了为什么这种方法是错误的。作者指出,虽然双亲委托机制确实可以阻止自定义的System类被加载,但通过自定义一个特殊的类加载器,可以绕过双亲委托机制,达到自定义System类的目的。作者呼吁读者对网上的内容持怀疑态度,并带着问题来阅读文章。 ... [详细]
  • 本文介绍了在MFC下利用C++和MFC的特性动态创建窗口的方法,包括继承现有的MFC类并加以改造、插入工具栏和状态栏对象的声明等。同时还提到了窗口销毁的处理方法。本文详细介绍了实现方法并给出了相关注意事项。 ... [详细]
  • 本文讨论了在VMWARE5.1的虚拟服务器Windows Server 2008R2上安装oracle 10g客户端时出现的问题,并提供了解决方法。错误日志显示了异常访问违例,通过分析日志中的问题帧,找到了解决问题的线索。文章详细介绍了解决方法,帮助读者顺利安装oracle 10g客户端。 ... [详细]
  • 本文介绍了RxJava在Android开发中的广泛应用以及其在事件总线(Event Bus)实现中的使用方法。RxJava是一种基于观察者模式的异步java库,可以提高开发效率、降低维护成本。通过RxJava,开发者可以实现事件的异步处理和链式操作。对于已经具备RxJava基础的开发者来说,本文将详细介绍如何利用RxJava实现事件总线,并提供了使用建议。 ... [详细]
  • 本文介绍了Java中Currency类的getInstance()方法,该方法用于检索给定货币代码的该货币的实例。文章详细解释了方法的语法、参数、返回值和异常,并提供了一个示例程序来说明该方法的工作原理。 ... [详细]
  • 本文介绍了解决java开源项目apache commons email简单使用报错的方法,包括使用正确的JAR包和正确的代码配置,以及相关参数的设置。详细介绍了如何使用apache commons email发送邮件。 ... [详细]
author-avatar
指定不告诉你
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有