【JUC】二十六、Java对象内存布局和对象头

文章目录

  • 0、前置
  • 1、对象的内存布局
  • 2、对象头之对象标记Mark Word
  • 3、对象头之类元信息
  • 4、实例数据
  • 5、对齐填充
  • 6、对象内存布局之JOL证明
  • 7、对象分代年龄
  • 8、压缩指针

0、前置

heap(堆区),分为新生区new、养老区old、元空间Metaspace,其中new区又分为伊甸园eden、幸存者0区s0、幸存者1区s1
在这里插入图片描述
new一个对象,在内存中的位置是堆 ⇒ 新生区⇒ 伊甸园区

Object object = new Object();

1、对象的内存布局

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

在这里插入图片描述

对象头:
在这里插入图片描述

对象头分为对象标记markOop和类元信息klassOop(两种英文都行,Oop用于JDK源代码)

在这里插入图片描述

2、对象头之对象标记Mark Word

public class ObjectHeadDemo {public static void main(String[] args) {Object o = new Object();   //这样new一个对象,占内存多少?System.out.println(o.hashCode());  //这个hashcode记录在对象的什么地方?synchronized (o){ //...同步锁标记?}System.gc(); //15次gc后,还没被处理的,可从新生区移动到养老区,怎么记录次数的?}
}

以下是对象头中的对象标记的结构:

在这里插入图片描述
在这里插入图片描述
在64位系统中,Mark Word占了8个字节,类型指针占了8个字节,一共是16个字节。单看Mark Word,8字节,64Bit,结构如下:

在这里插入图片描述

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

在这里插入图片描述
在这里插入图片描述
总之,对象布局、GC回收和锁升级就是对象标记MarkWord里面标志位的变化。

3、对象头之类元信息

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

public class Customer{int id;String name;
}//三个对象,同一个类,即同一个模板,对象头的类元指针指向相同
Customer c1 = new Customer();
Customer c2 = new Customer();
Customer c3 = new Customer();

一句话,每次new对象出来的,指向那个统一的多个实例对象的那个模板。

在这里插入图片描述

Q:对象头多大?

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

4、实例数据

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

如下:此时new这个对象,没有属性,只有一个对象头,16字节大小(忽略压缩指针的影响)

class Customer{}

引入属性:一个int 4 字节,一个boolean 1字节,16+4+1=21字节

class Customer{int id;boolean flag;
}

此时,21字节不是8的整数倍,需要进行对齐填充,补到24字节。

5、对齐填充

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

6、对象内存布局之JOL证明

JOL即Java Object LayOut,一个开箱即用的小工具,用于分析和展示Java对象在JVM中的大小布局。JOL官网:http://openjdk.java.net/projects/code-tools/jol/ 。

<!--jol-->
<dependency><groupId>org.openjdk.jol</groupId><artifactId>jol-core</artifactId><version>0.9</version>
</dependency>

小试一下:

//VM的详细情况
System.out.println(VM.current().details());
//所有的对象分配的字节数都是8的整数倍
System.out.println(VM.current().objectAlignment());

在这里插入图片描述

Object object = new Object();
System.out.println(ClassLayout.parseInstance(object).toPrintable());

在这里插入图片描述

类型指针只有4字节,而不是前面说的8字节的事,后面说。列的含义:

在这里插入图片描述
再用上面的Customer做测试:

class Customer{int id;boolean flag;
}
Customer customer = new Customer();
System.out.println(ClassLayout.parseInstance(customer).toPrintable());

可以发现无属性时,补齐到16字节,有属性时:

在这里插入图片描述

7、对象分代年龄

在这里插入图片描述

64位虚拟机下,对象分代年龄占4bit,也就是说,最大是1111,对应十进制就是15,这也是前面说的15次以后(到最大了)会从新生区到养老区的原因。MaxTenuringThreshold参数默认值就是15,在IDEA中添加JVM参数,改为16或更大:

//不同版本的Java不太一样,可改为17
-XX:MaxTenuringThreshold=16

在这里插入图片描述

再次运行,发现创建JVM都失败了:

在这里插入图片描述

8、压缩指针

在IDEA终端执行:

java -XX:+PrintCommandLineFlags -version

查看开启的一些参数:

在这里插入图片描述

发现这里使用了压缩指针,所以说前面看到类型指针只有4字节,而非理论里的8字节

从JDK 1.6开始,64位的JVM支持UseCompressedOops选项。其可对OOP(Ordinary Object Pointer,普通对象指针)进行压缩,使其只占用4个字节,以达到节约内存的目的。在JDK 8下,该选项默认启用。

-XX:+UseCompressedOops  // 开启指针压缩
-XX:-UseCompressedOops  // 关闭指针压缩

关闭压缩:

在这里插入图片描述

继续看new Object()对象的大小和分布,此时就是8+8了:

在这里插入图片描述

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C语言—每日选择题—Day46

第一题 1. 下列程序段的输出结果是&#xff08;&#xff09; #include <stdio.h> int main() {int x 1,a 0,b 0;switch(x) {case 0: b;case 1: a;case 2: a;b;}printf("a%d,b%d\n", a, b);return 0; } A&#xff1a;a2,b1 B&#xff1a;a1,b1 C&#xf…

探秘机器学习核心逻辑:梯度下降的迭代过程 (图文详解)

一 需求解函数 f() 和 g()函数分别为求y值和求导数的函数。 目的&#xff1a;求该函数的最小值&#xff1a; 代码&#xff1a; import numpy as np import matplotlib.pyplot as plt f lambda x : (x - 3.5) ** 2 - 4.5 * x 10 g lambda x : 2 * (x - 3.5) - 4.5x np.l…

接口管理——Swagger

Swagger是一个用于设计、构建和文档化API的工具集。它包括一系列工具&#xff0c;如Swagger Editor&#xff08;用于编辑Swagger规范&#xff09;、Swagger UI&#xff08;用于可视化API文档&#xff09;和Swagger Codegen&#xff08;用于根据API定义生成客户端库、server stu…

SpringCloud系列(二)| Nacos的安装与配置

Nacos是阿里巴巴提供的一个开源的可作为注册中心和配置中心的SpringCloud组件。 Nacos/nɑ:kəʊs/ 是 Dynamic Naming and Configuration Service 的首字母简称;一个更易于构 建云原生应用的动态服务发现、配置管理和服务管理平台。 简单来说Nacos有两个核心功能&#xff0c…

深度学习中的各类评价指标

深度学习中的各类评价指标 1 Dice Loss2 Precision&#xff08;精度&#xff09;3 Recall&#xff08;召回率&#xff09;4 F-Score5 mAP 1 Dice Loss Dice Loss&#xff0c;也叫Soft Dice Coefficient&#xff0c;是一种用于图像分割任务的损失函数。它基于目标分割图像与模型…

Uniapp项目打包到多个平台...

打包到微信小程序 先设置微信开发者工具的路径 运行到小程序模拟器&#xff0c;会自动打开微信开发者工具&#xff08;需要先在微信开发者工具->设置->安全设置->服务端口切换为打开状态&#xff09; 3. 微信开发者工具上传版本&#xff08;提示覆盖版本就可以了&a…

“百里挑一”AI原生应用亮相,百度智能云千帆AI加速器首个Demo Day来了!

作者简介&#xff1a; 辭七七&#xff0c;目前大二&#xff0c;正在学习C/C&#xff0c;Java&#xff0c;Python等 作者主页&#xff1a; 七七的个人主页 文章收录专栏&#xff1a; 七七的闲谈 欢迎大家点赞 &#x1f44d; 收藏 ⭐ 加关注哦&#xff01;&#x1f496;&#x1f…

用户管理第2节课 -- idea 2023.2 创建表

一、懂得 1.1编码格式是防止乱码的&#xff0c;utf-8是完全够的&#xff0c;那几个基本没差别 网址&#xff1a; 【IDEA——连接MySQL数据库&#xff0c;创建库和表】_idea中数据库-CSDN博客 这些是MySQL数据库中的一些术语&#xff0c;可以简单解释如下&#xff1a; 1、col…

第三十四周:文献阅读+LSTM学习

目录 摘要 Abstract 文献阅读&#xff1a;综合EMD-LSTM模型在城市排水管网水质预测中的应用 现有问题 提出方法 EMD-LSTM综合模型 研究框架 结论 Long Short-term Memory(长短期记忆) 1. LSTM的结构 2. Multiple-layer LSTM 3.3 LSTM Example 3. GRU LSTM实现PM2…

Java+SSM+MySQL基于微信的在线协同办公小程序(附源码 调试 文档)

基于微信的在线协同办公小程序 一、引言二、系统设计三、技术架构四、管理员功能设计五、员工功能设计六、系统实现七、界面展示八、源码获取 一、引言 随着科技的飞速发展&#xff0c;移动互联网已经深入到我们生活的各个角落。在这个信息时代&#xff0c;微信作为全球最大的…

靠谱的车- 华为OD统一考试(C卷)

靠谱的车- 华为OD统一考试&#xff08;C卷&#xff09; OD统一考试&#xff08;C卷&#xff09; 分值&#xff1a; 100分 题解&#xff1a; Java / Python / C 题目描述 程序员小明打了一辆出租车去上班。出于职业敏感&#xff0c;他注意到这辆出租车的计费表有点问题&#xf…

【知识】如何区分图论中的点分割和边分割

转载请注明出处&#xff1a;小锋学长生活大爆炸[xfxuezhang.cn] 以下两个概念在现有中文博客下非常容易混淆&#xff1a; edge-cut(边切割) vertex-partition(点分割)vertex-cut(点切割) edge-partition(边分割) 实际上&#xff0c;初看中文时&#xff0c;真的会搞不清楚。但…

黑豹程序员-EasyExcel实现导出

需求 将业务数据导出到excel中&#xff0c;老牌的可以选择POI&#xff0c;也有个新的选择EasyExcel。 有个小坑&#xff0c;客户要求样式比较美观&#xff0c;数字列要求千位符&#xff0c;保留2位小数。 可以用代码实现但非常繁琐&#xff0c;用模板就特别方便&#xff0c;模…

Pyhon基于YOLOV实现的车辆品牌及型号检测项目源码+模型+项目文档

项目运行运行录屏&#xff1a; Pyhon基于YOLOV实现的车辆品牌及型号检测项目运行录屏 完整代码下载地址&#xff1a;Pyhon基于YOLOV实现的车辆品牌及型号检测项目 项目背景&#xff1a; 车辆检测及型号识别广泛应用于物业&#xff0c;交通等的管理场景中。通过在停车场出入口…

Docker容器:Centos7搭建Docker镜像私服harbor

目录 1、安装docker 1.1、前置条件 1.2、查看当前操作系统的内核版本 1.3、卸载旧版本(可选) 1.4、安装需要的软件包 1.5、设置yum安装源 1.6、查看docker可用版本 1.7、安装docker 1.8、开启docker服务 1.9、安装阿里云镜像加速器 1.10、设置docker开机自启 2、安…

uni-app 设置tabBar的setTabBarBadge购物车/消息等角标

目录 一、效果二、代码实现二、全部代码1.index.vue2.cart.vue 三、真实案例参考最后 一、效果 二、代码实现 只要使用uni.setTabBarBadge和uni.removeTabBarBadge来进行对红点的设置和移除。 主要代码&#xff1a; //设置红点 uni.setTabBarBadge({index: 1, // 底部菜单栏…

19-数据结构-查找-散列查找

目录 一、散列查找结构思路图 二、哈希函数 三、解决冲突 1.开放地址法 1.1.线性探测法&#xff08;线性探测再散列法&#xff09; 1.2.平方探测法&#xff08;二次探测再散列&#xff09; 1.3.再散列法&#xff08;双散列法&#xff09; 2.拉链法 2.1简介 四、散列查…

Python 自动化之批量处理文件(一)

批量新建目录、文档Pro版本 文章目录 批量新建目录、文档Pro版本前言一、做成什么样子二、基本思路1.引入库2.基本架构 三、用户输入模块四、数据处理模块1.excel表格数据获取2.批量数据的生成 总结 前言 我来写一个不一样的批量新建吧。在工作中&#xff0c;有些同学应该会遇…

mybatis的快速入门以及spring boot整合mybatis(二)

需要用到的SQL脚本&#xff1a; CREATE TABLE dept (id int unsigned PRIMARY KEY AUTO_INCREMENT COMMENT ID, 主键,name varchar(10) NOT NULL UNIQUE COMMENT 部门名称,create_time datetime DEFAULT NULL COMMENT 创建时间,update_time datetime DEFAULT NULL COMMENT 修改…

SpringBoot 实现 elasticsearch 查询操作(RestHighLevelClient 的案例实战)

文章目录 1. 环境准备1. 查询全部2. 根据 name 查询 match 分词查询3. 根据 name 和 品牌查询 multiMatch 分词查询4. 根据 brand 查询 match 分词查询5. 按照价格 范围查询6. 精确查询7. boolQuery8. 分页9. 高亮查询9. 公共解析 上一节讲述了 SpringBoot 实现 elasticsearch …