JUC高级八-Java对象内存布局和对象头

news2024/10/5 17:27:25

JUC高级八-Java对象内存布局和对象头

1. 对象的内存布局

在HotSpot虚拟机里,对象在堆内存中的存储布局可以划分为三个部分:对象头(Header)实例数据(Instance Data)和对齐填充(Padding)(保证8个字节的倍数) 。

数组对象的对象头比常规对象多一个length,用于记录数组长度

image-20230409093814988

1.1 对象头

1.1.1 对象标记Mark Word

1.1.1.1 32位(看一下即可,不用学了,以64位为准)

image-20230409100947099

1.1.1.2 64位(重要)

image-20230409094132151

image-20230409094748251

image-20230409101153352

  • 默认存储对象的HashCode分代年龄锁标志位等信息。
  • 这些信息都是与对象自身定义无关的数据,所以MarkWord被设计成一个非固定的数据结构以便在极小的空间内存存储尽量多的数据。
  • 它会根据对象的状态复用自己的存储空间,也就是说在运行期间MarkWord里存储的数据会随着锁标志位的变化而变化。
1.1.1.2.1 源码分析

oop.hpp

image-20230409101311307

markOop.hpp

  • hash: 保存对象的哈希码
  • age: 保存对象的分代年龄
    • 从下图age:4可以看出分代年龄用4位表示,那么最大就是二进制1111即十进制15,所以新生代对象晋升为老年代对象需要分代年龄达到15次
  • biased_lock: 偏向锁标识位
  • lock: 锁状态标识位
  • JavaThread* :保存持有偏向锁的线程ID
  • epoch: 保存偏向时间戳

image-20230409101353805

1.1.1.2.2 markword(64位)分布图

对象布局、GC回收和后面的锁升级就是对象标记MarkWord里面标志位的变化

image-20230409101546174

1.1.2 类元信息(又叫类型指针)

image-20230409094415978

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

对象头多大?

在64位系统中,Mark Word占了8个字节,类型指针占了8个字节,一共是16个字节。

1.2 实例数据

image-20230409095312916

存放类的属性(Field)数据信息,包括父类的属性信息

1.3 对齐填充

虚拟机要求对象起始地址必须是8字节的整数倍。填充数据不是必须存在的,仅仅是为了字节对齐,这部分内存按8字节补充对齐。

Hotspot术语表官网

image-20230409095603588

底层源码理论证明

image-20230409095656594

  • _mark字段是mark word,_metadata是类指针klass pointer,

  • 对象头(object header)即是由这两个字段组成,这些术语可以参考Hotspot术语表,

    image-20230409095905448

2. 聊聊Object obj = new Object()

2.1 JOL工具–分析对象在JVM的大小和分布

JOL官网

pom依赖

<!--
官网:http://openjdk.java.net/projects/code-tools/jol/
定位:分析对象在JVM的大小和分布
-->
<dependency>
    <groupId>org.openjdk.jol</groupId>
    <artifactId>jol-core</artifactId>
    <version>0.9</version>
</dependency>

2.1.1 VM的细节详细情况示例

package site.zhourui.juc.objectHead;

import org.openjdk.jol.vm.VM;

public class JOLDemo {
    public static void main(String[] args) {
        //VM的细节详细情况
        System.out.println(VM.current().details());
        //对象对齐:所有的对象分配的字节都是8的整数倍。
        System.out.println(VM.current().objectAlignment());
    }
}

执行结果:

打印出VM的细节详细情况及对象对齐

image-20230409102937560

2.1.2 查看Object内存布局示例

package site.zhourui.juc.objectHead;

import org.openjdk.jol.info.ClassLayout;
import org.openjdk.jol.vm.VM;

public class JOLDemo {
    public static void main(String[] args) {
        Object o = new Object();
        System.out.println(ClassLayout.parseInstance(o));
    }
}

执行结果

之前说类型指针是8个字节现在只有4个字节?后面解释

image-20230409103905855

2.1.3 只有对象头没有其他任何示例数据的对象内存布局

package site.zhourui.juc.objectHead;

import org.openjdk.jol.info.ClassLayout;
import org.openjdk.jol.vm.VM;

public class JOLDemo {
    public static void main(String[] args) {
        Object o = new Object();
//        System.out.println(ClassLayout.parseInstance(o).toPrintable());
        Customer customer = new Customer();
        System.out.println(ClassLayout.parseInstance(customer).toPrintable());
    }
}

class Customer{//只有一个对象头的实例对象,16字节(忽路压缩指针的影响)+4字节+1字=-21字节----》对其填充,24字节
}

执行结果:

我们发现与new一个Object的对象内存布局一样的

image-20230409104253506

2.1.4 有实例数据对象内存布局

package site.zhourui.juc.objectHead;

import org.openjdk.jol.info.ClassLayout;
import org.openjdk.jol.vm.VM;

public class JOLDemo {
    public static void main(String[] args) {
        Object o = new Object();
//        System.out.println(ClassLayout.parseInstance(o).toPrintable());
        Customer customer = new Customer();
        System.out.println(ClassLayout.parseInstance(customer).toPrintable());
    }
}

class Customer{//只有一个对象头的实例对象,16字节(忽路压缩指针的影响)+4字节+1字=-21字节----》对其填充,24字节
    int id;
    boolean flag;
}

image-20230409104640034

2.1.5 GC年龄采用4位bit存储,最大为15,例如MaxTenuringThreshold参数默认值就是15

设置虚拟机分代年龄参数为16-XX:MaxTenuringThreshold=16

image-20230409105113817

执行结果:

说虚拟机分代年龄只能是0到15

image-20230409105131156

2.1.6 尾巴参数之压缩指针相关说明

2.1.6.1 查看jvm启动默认参数

-XX:+PrintCommandLineFlags -version

执行结果:

发现jvm启动的时候是默认帮我们开启了压缩指针UseCompressedClassPointers

就会导致我们的类型指针本来是8字节被压缩为4个字节

image-20230409105522364

2.1.6.2 关闭压缩指针再次查看对象内存布局

-XX:-UseCompressedClassPointers

执行结果:

发现没有对齐填充了,我们的类型指针是8字节

image-20230409110004849

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/413323.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

【java】泛型编程

文章目录泛型类泛型与多态泛型方法泛型界限设置上界设置下界类型擦除函数式接口Supplier供给型函数式接口Consumer消费型函数式接口Function函数型函数式接口Predicate断言型函数式接口判空包装泛型类 package com.test.entity; public class Score<T> {String name;Str…

一文搞懂Session和JWT登录认证

前言 目前在开发的小组结课项目中用到了JWT认证&#xff0c;简单分享一下&#xff0c;并看看与Session认证的异同。 登录认证&#xff08;Authentication&#xff09;的概念非常简单&#xff0c;就是通过一定手段对用户的身份进行确认。 我们都知道 HTTP 是无状态的&#xf…

模型实战(9)之YOLOv8预测模块predictor详解、预测视频后同时保存结果视频+目标帧

YOLOv8预测模块predictor详解、预测视频后同时保存结果视频+目标帧 Ultralytics YOLOv8Ultralytics YOLOv8是最新版本的YOLO对象检测和图像分割模型。 作为一种尖端的、最先进的(SOTA)模型,YOLOv8建立在以前版本的成功基础上,引入了新的功能和改进,以增强性能、灵活性和效率…

高速Serdes技术(FPGA领域应用)

目录引入一、Serdes&#xff08;概念-历程&#xff09;1、概念2、技术现状3、发展历程二、Serdes结构三、在FPGA领域中的运用四、Serdes跟Lvds的关系五、Xilinx 有关 serdes的文档六、参考文献引入 回顾接口技术发展历史&#xff0c;其实数据的传输最开始是低速的串行接口&…

202307读书笔记|《双向奔赴的爱,才是人间理想》——爱是双向奔赴,共同成长

《双向奔赴的爱&#xff0c;才是人间理想》作者燕七&#xff0c;读作者的第一本书是《鲸鱼安慰&#x1f433;了大海》可太美了&#xff0c;这次订阅通知这本&#xff0c;立马加入了书架&#xff0c;跑完步读了起来。没有第一本惊艳&#xff0c;但也不错&#xff0c;值得一读&am…

JavaScript对象的属性描述符(Property Descriptor)介绍

JavaScript对象的属性描述符&#xff08;Property Descriptor&#xff09;介绍 JavaScript 中的对象&#xff08;Object&#xff09;是一个包含相关数据和方法的集合&#xff0c;通常由一些变量和函数组成&#xff0c;我们称之为对象里面的属性&#xff08;property&#xff0…

java springboot工程RESTful入门案例 认识请求类型 参数

我们先创建一个java的springboot工程 然后 我们先用老方式试一下 在启动类的同级创建目录controller 下面创建一个类 叫 UserController 参考代码如下 package com.example.threshold.controller;import org.springframework.web.bind.annotation.GetMapping; import org.spri…

负载均衡与DNS轮询

负载均衡 load balance 负载均衡&#xff08;Load Balancing&#xff09;是一种将工作负载&#xff08;Workload&#xff09;分摊到多个计算资源&#xff08;服务器、存储设备、网络设备等&#xff09;上的技术&#xff0c;目的是提高系统的可用性、性能和扩展性。负载均衡可以…

序列化和反序列化二叉树 -----前序,中序,后序,层序

目录 一.序列化和反序列化 1.什么是序列化和反序列化 二.前序遍历 1.序列化 1.问题分析 2.代码实现 2.反序列化 1.问题分析 2.代码实现 三.后序遍历 1.序列化 1.思路分析 2.代码实现 2.反序列化 1.思路分析 2.代码实现 四.中序遍历 1.序列化 1.思路分析 2.代…

SpringBoot 使用Prometheus采集自定义指标数据

一、我们需要什么指标 对于DDD、TDD等&#xff0c;大家比较熟悉了&#xff0c;但是对于MDD可能就比较陌生了。MDD是Metrics-Driven Development的缩写&#xff0c;主张开发过程由指标驱动&#xff0c;通过实用指标来驱动快速、精确和细粒度的软件迭代。MDD可使所有可以测量的东…

RPC调用框架简单介绍

一.Thrift Apache Doris目前使用的RPC调度框架。Thrift是一款基于CS&#xff08;client -server&#xff09;架构的RPC通信框架&#xff0c;开发人员可以根据定义Thrift的IDL(interface decription language)文件来定义数据结构和服务接口&#xff0c;灵活性高&#xff0c;支持…

Leetcode.2583 二叉树中的第 K 大层和

题目链接 Leetcode.2583 二叉树中的第 K 大层和 Rating &#xff1a; 1374 题目描述 给你一棵二叉树的根节点 root和一个正整数 k 。 树中的 层和 是指 同一层 上节点值的总和。 返回树中第 k 大的层和&#xff08;不一定不同&#xff09;。如果树少于 k 层&#xff0c;则返…

INFINONE XC164单片机逆向记录(5)C166地址系统

本人所写的博客都为开发之中遇到问题记录的随笔,主要是给自己积累些问题。免日后无印象,如有不当之处敬请指正(欢迎进扣群 24849632 探讨问题); 写在专栏前面https://blog.csdn.net/Junping1982/article/details/129955766 INFINONE XC164单片机逆向记录(1)资料准备

Python爬虫知识回顾

之前一直沉溺于java&#xff0c;jsp&#xff0c;ssh&#xff0c;db等爬虫&#xff0c;现在又要开始走python的老路了。常用的requests库&#xff0c;通过requests对象的get方法&#xff0c;获取一个response对象。jsp的东西。 其中timeout,proxies,headers,cookies,verify,是我…

webgl-画指定颜色三角形

html <!DOCTYPE html> <head> <style> *{ margin: 0px; padding: 0px; } </style> </head> <body> <canvas id webgl> 您的浏览器不支持HTML5,请更换浏览器 </canvas> <script src"./main.js"></script&g…

JUC之CountDownLatch与CyclicBarrier

1.前言 在java.util.concurrent包中为我们提供了很多的线程同步工具类&#xff0c;例如CountDownLatch与CyclicBarrier&#xff0c;那么它们主要的用途是什么呢&#xff1f;且看后续分析。 2.CountDownLatch 2.1 什么是CountDownLatch CountDownLatch&#xff0c;顾名思义&…

从ReentrantLock角度解析AQS

一、概述 闲来不卷&#xff0c;随便聊一点。 一般情况下&#xff0c;大家系统中至少也是JDK8了&#xff0c;那想必对于JDK5加入的一系列功能并不陌生吧。那时候重点加入了java.util.concurrent并发包&#xff0c;我们简称为JUC。JUC下提供了很多并发编程实用的工具类&#xf…

风光及负荷多场景随机生成与缩减

目录 1 主要内容 计算模型 场景生成与聚类方法应用 2 部分程序 3 程序结果 4 程序链接 1 主要内容 该程序方法复现了《融合多场景分析的交直流混合微电网多时间尺度随机优化调度策略》3.1节基于多场景技术的随机性建模部分&#xff0c;该部分是随机优化调度的重要组成部分…

记录-css实现交融文字效果

这里给大家分享我在网上总结出来的一些知识&#xff0c;希望对大家有所帮助 CSS是有魔法的&#xff0c;我们今天来实现一个CSS的动画效果&#xff0c;只需要几行代码就可以搞定。 第一步、我们要将一行文字从中间展开 <!DOCTYPE html> <html lang"en"> &…

面试官:聊聊js原型

一分钟了解原型对象 js分为函数对象和普通对象 &#xff0c;每个对象都有__proto__属性&#xff0c;但是只有函数对象才有prototype属性&#xff0c;prototype属性就是函数的原型对象。 比如说 构造函数通过new 实化一个实例对象&#xff0c;实例对象的__proto__ 指向原型对象…