jvm之对象大小分析

news2024/11/28 18:47:19

写在前面

本文看下计算对象大小相关内容。

1:基础内容

1.1:对象的结构

一个对象由对象头和对象体组成,其中对象头包含如下内容:

标记字(mark word):存放GC年龄信息,对象锁信息等,占用8个字节
class指针:指向方法区中的class文件信息,占用4个字节(指针压缩)
数组长度信息(array length):数组特有,记录数组的长度,int表示,所以是8个字节,该项非数组可忽略

对象体存储的是具体的对象内容以及内部padding:

对象内容:具体的属性信息
内部padding:如果不是8字节的整数倍,则填充为8字节的整数倍,因为CPU是以8byte为单位来获取数据的

当对象头和对象体的总大小不是8byte的整数倍时需要通过外部aligment来填充到整数倍,整体结构如下:

在这里插入图片描述

因此就算是一个空对象其大小也至少是标记字8字节+class指针4字节+对象内容0字节+外部alignment4字节=16字节。如下定义一个类:

public class EmptyObject {
}

然后创建100个对象实例,如下:

public class Main {

    public static void main(String[] args) throws InterruptedException {
        List<EmptyObject> oneHundredList = new ArrayList<>();
        for (int i = 0; i < 100; i++) {
            oneHundredList.add(new EmptyObject());
        }
        Thread.sleep(Integer.MAX_VALUE);
    }
}

如下查看:

C:\Users\Administrator>jps -l
7984 org.jetbrains.jps.cmdline.Launcher
12692
20196 sun.tools.jps.Jps
3512 dongshi.daddy.objectsize.Main
14892
19580 org.jetbrains.idea.maven.server.RemoteMavenServer36
C:\Users\Administrator>jmap -histo 3512 > d:\\test\\emptyobj100.txt

在这里插入图片描述

可以看到每个是16字节,当我们定义一个int属性,大小是多少呢?依然是16字节,因为有了4字节的int就不要4字节的外部alignment了,如下:

public class EmptyObject {
    int num;
}

重复执行创建100个对象实例的程序:

C:\Users\Administrator>jps -l
11780 sun.tools.jps.Jps
12692
12568 dongshi.daddy.objectsize.Main
14892
19356 org.jetbrains.jps.cmdline.Launcher
19580 org.jetbrains.idea.maven.server.RemoteMavenServer36

C:\Users\Administrator>jmap -histo 12568 > d:\\test\\withint.txt

在这里插入图片描述

那如果我们再添加一个short成员变量,此时一个EmptyObject占用多大内存呢?答案是24字节,计算如下:

对象头标记字:8字节
对象头class指针:4字节

对象内容int:4字节
对象内容short:2字节
内部padding:2字节

此时总共20字节,不是8整倍数,所以需要外部alignment4字节

所以总共是24字节

修改如下:

public class EmptyObject {
    int num;
    short shortNum;
}

重新生成100个对象实例后查看:

C:\Users\Administrator>jmap -histo 3952 | findstr ":EmptyObject"

C:\Users\Administrator>jmap -histo 3952 | findstr "EmptyObject"
  28:           100           2400  dongshi.daddy.objectsize.EmptyObject

可以看到确实是24字节。

2:包装类型和原生类型

先说结论,包装数据类型要比原生类型占用更多的内存,因为多了对象头和填充的内存占用,分别来看下Integer和Long。

2.1:Integer

对于int,其占用4个字节,但是如果是其包装类型Integer,则要占用(对象头标记字8字节+对象头class指针4字节+对象内容int本身4字节=16字节),如下也可以验证:

C:\Users\Administrator>jmap -histo 3952 | findstr "java.lang.Integer"
  19:           258           4128  java.lang.Integer

总大小4128除以对象个数258等于16字节。

2.2:Long

对于long,其占用8个字节,但是如果是其包装类型Long,则要占用(对象头标记字8字节+对象头class指针4字节+对象内容int本身8字节+外部alignment4字节=24字节),如下也可以验证:

C:\Users\Administrator>jmap -histo 7212 | findstr "java.lang.Long"
  28:           100           2400  java.lang.Long

可以看到每个的大小是2400/100=24字节

所以在实际编码中,能使用基本数据类型的还是使用基本数据类型,因为包装数据类型的内存占用量相比于基础数据类型要多出几倍。

3:数组

以int数组为例,对于一维的int数组,其结构如下:

在这里插入图片描述

因此如果是int[256]则大小是(标记字8字节+class指针4字节+数组长度4字节+内容256*4=1040字节)

对于二维数组int[dim1][dim2]而言,每个int[dim2]都是使用一个额外的对象来表示的,因此会占用更大的内存空间,如果我们将int[256]使用int[128][2]来表示的话,则结构如下图:

在这里插入图片描述

每个元素的大小是(指针4字节+int[2]对象24字节=28字节),共128个,所以大小是128*28=3584字节,再加上第一纬的标记头8字节,class指针4字节,数组长度4字节,共3600字节,可看到存储相同量的元素,int[128][2]比int[256]多占用了(3600-1040=2560字节)的内存空间。

所以,在实际工作中,尽量避免使用多维数组,有需要也尽量使用一维数组来实现,将一维数组折叠一下就行了。

4:String

想要分析处String占用的内存大小,需要先来看下String的定义(只列出会占用堆内存的)

public final class String
    implements java.io.Serializable, Comparable<String>, CharSequence {
    /** The value is used for character storage. */
    private final char value[];

    /** Cache the hash code for the string */
    private int hash; // Default to 0
}

结构如下:

在这里插入图片描述

则一个空string占用的大小是40字节,如果是不包括String对象头的话,则大小是24字节。

5:普通的类

如下的类:

public class EmptyObject {
    int a;
    byte b;
    Integer c = new Integer(10);
}

内存结构如下:

在这里插入图片描述

所以总大小是(标记字8字节+class指针4字节+int a 4字节+byte b 1字节+Integer c指针 4字节=21字节),再对齐,因此是24字节,如下验证:

public class Main {

    public static void main(String[] args) throws InterruptedException {
        List<EmptyObject> oneHundredList = new ArrayList<>();
        for (int i = 0; i < 100; i++) {
            oneHundredList.add(new EmptyObject());
        }
        Thread.sleep(Integer.MAX_VALUE);
    }
}
:\Users\Administrator>jps -l
13200 dongshi.daddy.objectsize.Main
12692
6824 sun.tools.jps.Jps
14892
19580 org.jetbrains.idea.maven.server.RemoteMavenServer36
3308 org.jetbrains.jps.cmdline.Launcher

C:\Users\Administrator>jmap -histo 13200 | findstr "EmptyOb"
  28:           100           2400  dongshi.daddy.objectsize.EmptyObject

可以看到每个确实是24字节。

写在后面

参考文章列表

Java中的String到底占用多大的内存空间?带你一步步验证! 。

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

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

相关文章

Hightopo 使用心得(1)- 基本概念

Hightopo 公司 3D 可视化产品有对应的官方手册。但是这些手册内容比较多。对于想学习的新同学来说可能相对比较繁琐。这里本人根据个人使用经验做了一些总结。希望对读者有所帮助。 官方手册地址&#xff1a;Structure (hightopo.com) 本文会提到一些前端开发的概念&#xff…

pdf怎么压缩得小一点?软件压缩更高效

PDF可以在不同操作系统和设备上实现高保真的排版和格式化。然而&#xff0c;随着文档的不断增多和文件大小的增加&#xff0c;传输和存储PDF文件也变得越来越困难。为了解决这个问题&#xff0c;可以使用PDF压缩技术来减小文件大小&#xff0c;提高传输效率。本文将介绍PDF压缩…

pdf转jpg怎么转?转换软件分享

随着数字化时代的到来&#xff0c;我们处理和共享信息的方式也在不断进步。在许多情况下&#xff0c;我们需要将PDF文档转换为图像格式&#xff0c;以便更方便地在网站、社交媒体或其他数字平台上与他人共享。本文将介绍如何将PDF文件转换为JPG图像格式。 有许多在线工具和软件…

1929-2022年全球站点的逐月平均气温数据

气象数据是在各项研究中都经常使用的数据&#xff0c;气象指标包括气温、风速、降水、湿度等指标&#xff0c;其中又以气温指标最为常用&#xff01;说到气温数据&#xff0c;最详细的气温数据是具体到气象监测站点的气温数据&#xff01;本次我们为大家带来的就是具体到气象监…

制船业智慧转型,3D轻量化工具赋能数字化!

随着科技的不断进步&#xff0c;计算机辅助设计&#xff08;CAD&#xff09;和三维建筑模型技术在造船业中扮演着重要角色。造船业是一个复杂而庞大的行业&#xff0c;涉及到船舶设计、建造模型、制造和施工等多个环节。 为了提高效率、降低成本并保证质量&#xff0c;传统的手…

记录为什么程序跑着跑着突然重启

这里写自定义目录标题 欢迎使用Markdown编辑器新的改变功能快捷键合理的创建标题&#xff0c;有助于目录的生成如何改变文本的样式插入链接与图片如何插入一段漂亮的代码片生成一个适合你的列表创建一个表格设定内容居中、居左、居右SmartyPants 创建一个自定义列表如何创建一个…

3. 自然语言处理NLP:具体用途(近义词类比词;情感分类;机器翻译)

一、求近义词和类比词 1. 近义词 方法一&#xff1a;在嵌入模型后&#xff0c;可以根据两个词向量的余弦相似度表示词与词之间在语义上的相似度。 方法二&#xff1a;KNN&#xff08;K近邻&#xff09; 2. 类比词 使用预训练词向量求词与词之间的类比关系。eg&#xff1a;man&a…

同等学力申硕在职研究生,到底有没有含金量

&#x1f50e; 同等学力申硕的含金量怎么样&#xff1f;值得报考吗&#xff1f; 所谓同等学力申硕的含金量&#xff0c;其实就是指硕士学位证书所能带来的价值。 同等学力申硕不属于学历教育&#xff0c;硕士学位证书不能提高学历&#xff0c;也就是说我们毕业之后&#xff0…

如何在 GNU Linux 上通过 Nvm 安装 Node 和 Npm?

Node.js 是一个流行的 JavaScript 运行时环境&#xff0c;用于开发服务器端和网络应用程序。它带有一个强大的软件包管理器 npm&#xff0c;可以方便地安装和管理 JavaScript 包和依赖项。在 GNU/Linux 系统上&#xff0c;使用 Nvm&#xff08;Node Version Manager&#xff09…

项目部署——后端Springboot+前端VUE3

后端&#xff1a; 1.JDK环境配置&#xff1a; 服务器本身是没有装JDK的&#xff0c; 输入&#xff1a;java -version&#xff1b;会显示让你安装JDK&#xff0c; 输入&#xff1a;apt install openjdk-17-jre-headless 我们项目后端开发用的是JDK17&#xff0c;所以服务器也安…

ADManager Plus:微软的全面活动目录管理解决方案

摘要&#xff1a;ADManager Plus是微软推出的一款全面活动目录&#xff08;Active Directory&#xff09;管理解决方案。它提供了一系列强大的功能&#xff0c;帮助组织简化和自动化活动目录管理&#xff0c;提高安全性和效率。本文将介绍ADManager Plus的特点、优势以及在企业…

如何在华为OD机试中获得满分?Java实现【递增字符串】一文详解!

✅创作者:陈书予 🎉个人主页:陈书予的个人主页 🍁陈书予的个人社区,欢迎你的加入: 陈书予的社区 🌟专栏地址: Java华为OD机试真题(2022&2023) 文章目录 1. 题目描述2. 输入描述3. 输出描述4. Java算法源码5. 测试6.解题思路1. 题目描述 定义字符串完全由“A’和…

【Linux】编译器gcc和g++与调试器gdb的使用

文章目录 一、Linux编译器-gcc/g1.程序运行的四个阶段1.1 预处理1.2 编译1.3 汇编1.4 链接 2.链接方式与函数库2.1 动态链接与静态链接2.2 动态库与静态库3.gcc/g的使用 二、Linux调试器--gdb1.debug与release2.gdb 的使用 一、Linux编译器-gcc/g 1.程序运行的四个阶段 我们知…

RK3588-EDGE Ethernet驱动(一)

一:概述 以太网从硬件层来讲大致可分为三部分:CPU,MAC,PHY。 上述三部分有以下几种组成方式,而非封装在一颗IC种。 CPU内部集成了MAC和PHY,难度较高CPU内部集成MAC,PHY采用独立芯片(主流方案)CPU不集成MAC和PHY,MAC和PHY采用独立芯片或者集成芯片(高端采用)其中常说的…

MetaHuman结合第三人称角色,增加走路跑步动画

一、准备第三人称角色资源 1.新建工程选择第三人称角色,将第三人称角色拷贝到MetaHumans目录下 2.复制一个数字人,父类指定为BPThirdPersonCharacter 3.将Body移动到Mesh下边 调整好姿势和位置 4.可以将头发的UseCards设置为true,可以减少性能消耗 5.编译报错修复

【 网络常见的 9 大命令,非常实用!】

网络常见的 9 大命令&#xff0c;非常实用&#xff01; 1&#xff0e;ping 命令 PING &#xff08;Packet Internet Groper&#xff09;&#xff0c; 因特网包探索器&#xff0c;用于测试网络连接量的程序 。Ping是工作在 TCP/IP网络体系结构中应用层的一个服务命令&#xff…

随机网络构建

随机网络构建 文章目录 随机网络构建[toc]1 随机网络定义2 网络拓扑性质2.1 边数分布2.2 度分布 3 代码实现 1 随机网络定义 随机网络与规则网络相对应&#xff0c;最为经典的随机网络模型是Erds和Rnyi研究的ER随机图模型&#xff0c;ER随机图模型有两种定义方式&#xff1a; …

(2020,ADA)用有限的数据训练生成对抗网络

Training generative adversarial networks with limited data 公众号&#xff1a;EDPJ 目录 0. 摘要 1. 简介 2. GAN 中的过度拟合 2.1 随机鉴别器增强&#xff08;stochastic discriminator augmentation&#xff09; 2.2 设计不泄漏的增强 2.3 我们的增强流程 3. 自…

阿里云轻量服务器--Docker--RocketMq安装

前言&#xff1a;本文介绍使用docker 部署-RocketMq&#xff1b; 1 RocketMq 介绍&#xff1a; Apache RocketMQ是一款开源的分布式消息中间件&#xff0c;具有高吞吐量、高可用性、高伸缩性和灵活的可靠消息传输机制等特点。RocketMQ支持多种消息模式&#xff0c;包括异步传…

【App自动化测试】(十八)多设备管理平台——openSTF

目录 1. openSTF2. openSTF的安装部署2.1 MacOS2.2 Windows 3. STF操作3.1 基础操作——远程调试虚拟设备3.2 高阶操作——远程调试真机 1. openSTF OpenSTF&#xff1a;是一个手机设备管理平台&#xff0c;可以对手机进行远程管理、调试、远程手机桌面监控等操作。 特点&…