我的编程空间,编程开发者的网络收藏夹
学习永远不晚

从小工到专家的 Java 进阶之旅:HotSpot虚拟机对象探秘

短信预约 -IT技能 免费直播动态提醒
省份

北京

  • 北京
  • 上海
  • 天津
  • 重庆
  • 河北
  • 山东
  • 辽宁
  • 黑龙江
  • 吉林
  • 甘肃
  • 青海
  • 河南
  • 江苏
  • 湖北
  • 湖南
  • 江西
  • 浙江
  • 广东
  • 云南
  • 福建
  • 海南
  • 山西
  • 四川
  • 陕西
  • 贵州
  • 安徽
  • 广西
  • 内蒙
  • 西藏
  • 新疆
  • 宁夏
  • 兵团
手机号立即预约

请填写图片验证码后获取短信验证码

看不清楚,换张图片

免费获取短信验证码

从小工到专家的 Java 进阶之旅:HotSpot虚拟机对象探秘

对象的创建(以 new 关键字为例)

创建过程

  1. Java 虚拟机遇到字节码new指令,首先检查new指令参数是否能够在常量池中定位到一个类的符号引用

如果是,继续下一步

如果否,执行类加载过程

如果是,检查这个符号引用代表的类是否已经被加载、解析和初始化

如果否,执行类加载

  1. 虚拟机为新生对象分配内存(对象所需内存大小在类加载完成后即可确定)
  2. 虚拟机将分配的内存空间(不包括对象头)初始化为零值。
  3. 虚拟机对对象进行必要设置,比如设置对象头信息:
  4. 对象是哪个类的实例
  5. 如何找到类的元数据信息
  6. 对象的哈希码
  7. 对象的 GC 分代年龄
  8. new指令之后会接着执行()方法,按照程序员意愿初始化对象

内存分配

  1. 内存分配算法:拟机为新生对象分配内存有指针碰撞和空闲列表两种方式,具体选择哪种,取决于垃圾收集器是否带有空间压缩整理的能力。Serial、ParNew 带压缩整理,采用指针碰撞;CMS 基于清除算法,采用空闲列表。

指针碰撞 (Bump The Pointer):堆内存绝对规整,已使用的在一边,未使用的在另外一遍,中间通过指针作为分界点指示器,分配内存即移动指针。

空闲列表 (Free List):堆内存不规整,已使用与未使用相互交错,需要维护一个列表,记录哪些内存块可用,分配的时候从列表中找到一块足够大的空间划分给对象实例,并更新列表记录。

  1. 线程安全问题:创建对象比较频繁,需要保证线程安全,避免多个对象分配了相同的内存区域,一般是两种方式:

同步处理:虚拟机采用CAS+失败重试方式保证更新操作的原子性

本地线程分配缓冲:把内存分配的动作按照线程划分在不同空间之中进行,即每个线程在 Java 堆中预先分配一小块内存,称为本地线程分配缓冲 (Thread Local Allocation Buffer, TLAB),哪个线程要分配内存,就在哪个线程的本地缓冲区中分配,只有本地缓冲缓冲区用完了,分配新的缓冲区时才需要同步锁定。是否使用 TLAB,可以通过参数-XX:+/-UseTLAB参数设定。

对象的内存布局

  1. 对象头 (Header)

用于存储对象自身运行时数据:哈希码 (Hash Code)、GC 分代年龄、锁状态标志、线程持有的锁、偏向线程 ID、偏向时间戳等,长度在 32 位和 64 位虚拟机分别是 32 比特和 64 比特,官方称为 Mark Word。

类型指针,即对象指向它的类型元数据指针,Java 虚拟机通过这个指针来确定该对象是哪个类的实例。

如果对象是数组,还有一个数据记录数组长度

  1. 实例数据 (Instance Data):即程序代码里面定义的各种类型的字段内容。存储顺序受虚拟机分配策略 (-XX:FieldsAllocationStyle 参数)和字段在 Java 源码中定义顺序影响。HotSpot 虚拟机默认分配顺序为 longs/doubles、ints、shorts/charts、bytes/booleans、oops(Ordinary Object Pointers, OOPS),即相同宽度字段被分配到一起存放,在满足这个前提条件情况下,在父类中定义的变了会出现在子类之前。如果 HotSpot 虚拟机的+XX:CompactFields 参数设置为 true,子类中较窄的变量也允许插入父类变量的空隙中,以节省空间。
  2. 对齐填充 (Padding):占位符作用。HotSpot 虚拟机的自动内存管理系统要求对象起始地址必须是 8 字节的整数倍。

对象的访问定位

Java 程序会通过栈上的 reference 数据来操作堆上的具体对象,主流的访问方式主要有使用句柄和直接指针两种:

  • 使用句柄:Java 堆中将可能会划分出一块内存来作为句柄池,reference 中存储的是对象的句柄地址,句柄中包含了对象实例数据和类型数据各自的具体地址信息。好处是解耦,reference 中存储的是稳定句柄地址,在对象被移动(垃圾回收等)时只会改变句柄中实例数据指针,而 reference 本身不需要修改。
  • 直接指针:Java 堆中的对象布局必须考虑如何放置访问类型数据的相关信息,reference 中存储的是对象地址。好处是速度快,节省一次指针定位时间开销,HotSpot 主要使用直接指针。

使用句柄

直接指针


免责声明:

① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。

② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341

从小工到专家的 Java 进阶之旅:HotSpot虚拟机对象探秘

下载Word文档到电脑,方便收藏和打印~

下载Word文档

猜你喜欢

从小工到专家的 Java 进阶之旅:HotSpot虚拟机对象探秘

Java 堆中将可能会划分出一块内存来作为句柄池,reference 中存储的是对象的句柄地址,句柄中包含了对象实例数据和类型数据各自的具体地址信息。好处是解耦,reference 中存储的是稳定句柄地址,在对象被移动(垃圾回收等)时只会改

编程热搜

  • Python 学习之路 - Python
    一、安装Python34Windows在Python官网(https://www.python.org/downloads/)下载安装包并安装。Python的默认安装路径是:C:\Python34配置环境变量:【右键计算机】--》【属性】-
    Python 学习之路 - Python
  • chatgpt的中文全称是什么
    chatgpt的中文全称是生成型预训练变换模型。ChatGPT是什么ChatGPT是美国人工智能研究实验室OpenAI开发的一种全新聊天机器人模型,它能够通过学习和理解人类的语言来进行对话,还能根据聊天的上下文进行互动,并协助人类完成一系列
    chatgpt的中文全称是什么
  • C/C++中extern函数使用详解
  • C/C++可变参数的使用
    可变参数的使用方法远远不止以下几种,不过在C,C++中使用可变参数时要小心,在使用printf()等函数时传入的参数个数一定不能比前面的格式化字符串中的’%’符号个数少,否则会产生访问越界,运气不好的话还会导致程序崩溃
    C/C++可变参数的使用
  • css样式文件该放在哪里
  • php中数组下标必须是连续的吗
  • Python 3 教程
    Python 3 教程 Python 的 3.0 版本,常被称为 Python 3000,或简称 Py3k。相对于 Python 的早期版本,这是一个较大的升级。为了不带入过多的累赘,Python 3.0 在设计的时候没有考虑向下兼容。 Python
    Python 3 教程
  • Python pip包管理
    一、前言    在Python中, 安装第三方模块是通过 setuptools 这个工具完成的。 Python有两个封装了 setuptools的包管理工具: easy_install  和  pip , 目前官方推荐使用 pip。    
    Python pip包管理
  • ubuntu如何重新编译内核
  • 改善Java代码之慎用java动态编译

目录