Java中对象的内存消耗是多少?

2023-11-22

一个具有 100 个属性的对象所消耗的内存空间与 100 个对象(每个对象各有一个属性)所消耗的内存空间相同吗?

为一个对象分配了多少内存?
添加属性时使用了多少额外空间?


Mindprod指出这不是一个容易回答的问题:

JVM 可以自由地以任何内部喜欢的方式存储数据,无论是大端还是小端,以及任意数量的填充或开销,尽管基元的行为必须就像它们具有官方大小一样。
例如,JVM 或本机编译器可能决定存储boolean[]64 位长块,例如BitSet。它不必告诉您,只要程序给出相同的答案即可。

  • 它可能会在堆栈上分配一些临时对象。
  • 它可能会优化一些完全不存在的变量或方法调用,用常量替换它们。
  • 它可能会对方法或循环进行版本控制,即编译一个方法的两个版本,每个版本都针对特定情况进行优化,然后预先决定调用哪个版本。

当然,硬件和操作系统有多层缓存,芯片缓存、SRAM 缓存、DRAM 缓存、普通 RAM 工作集和磁盘上的后备存储。您的数据可能在每个缓存级别都有重复。所有这些复杂性意味着您只能非常粗略地预测 RAM 消耗。

测量方法

您可以使用Instrumentation.getObjectSize()获取对象消耗的存储空间的估计值。

可视化actual对象布局、占用空间和引用,您可以使用JOL(Java 对象布局)工具.

对象标头和对象引用

在现代 64 位 JDK 中,对象具有 12 字节标头,填充为 8 字节的倍数,因此最小对象大小为 16 字节。对于 32 位 JVM,开销为 8 字节,填充为 4 字节的倍数。(From 德米特里·斯皮哈尔斯基的回答, 杰恩的回答, and Java世界.)

通常,引用在 32 位平台上为 4 个字节,在 64 位平台上最多为-Xmx32G;以及 32Gb 以上的 8 个字节(-Xmx32G). (See 压缩对象引用.)

因此,64 位 JVM 通常需要多出 30-50% 的堆空间。(我应该使用 32 位还是 64 位 JVM?,2012,JDK 1.7)

装箱类型、数组和字符串

与原始类型相比,盒装包装器有开销(来自Java世界):

  • Integer: 16 字节结果比我预期的要差一些,因为int值只能容纳 4 个额外字节。使用Integer与将值存储为原始类型相比,我花费了 300% 的内存开销

  • Long:也是 16 字节:显然,堆上的实际对象大小取决于特定 CPU 类型的特定 JVM 实现所完成的低级内存对齐。它看起来像一个Long是 8 个字节的对象开销,加上实际的 long 值的 8 个字节。相比之下,Integer有一个未使用的 4 字节漏洞,很可能是因为我使用的 JVM 强制在 8 字节字边界上对齐对象。

其他容器也很昂贵:

  • 多维数组: 它提供了另一个惊喜。
    开发人员通常采用类似的结构int[dim1][dim2]在数值和科学计算方面。

    In an int[dim1][dim2]数组实例,每个嵌套int[dim2]数组是一个Object在自己的权利。每个都会增加通常的 16 字节数组开销。当我不需要三角形或参差不齐的数组时,这代表纯粹的开销。当数组维度差异很大时,影响会更大。

    例如,一个int[128][2]实例占用 3,600 字节。与 1,040 字节相比int[256]实例使用(具有相同的容量),3,600 字节代表 246% 的开销。在极端情况下byte[256][1],开销系数几乎是19!与 C/C++ 情况相比,相同的语法不会增加任何存储开销。

  • String: a String的内存增长跟踪其内部字符数组的增长。但是,那Stringclass 又增加了 24 个字节的开销。

    对于一个非空的String如果大小为 10 个字符或更少,则相对于有用负载(每个字符 2 个字节加上长度 4 个字节)而言,增加的开销成本范围为 100% 到 400%。

结盟

考虑一下这个示例对象:

class X {                      // 8 bytes for reference to the class definition
   int a;                      // 4 bytes
   byte b;                     // 1 byte
   Integer c = new Integer();  // 4 bytes for a reference
}

一个天真的总和表明,一个实例X将使用 17 个字节。但是,由于对齐(也称为填充),JVM 以 8 字节的倍数分配内存,因此它会分配 24 字节,而不是 17 字节。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

Java中对象的内存消耗是多少? 的相关文章

  • Java new Date() 打印

    刚刚学习 Java 我知道这可能听起来很愚蠢 但我不得不问 System out print new Date 我知道参数中的任何内容都会转换为字符串 最终值是 new Date 返回对 Date 对象的引用 那么它是如何打印这个的呢 Mo
  • 在画布上绘图

    我正在编写一个 Android 应用程序 它可以在视图的 onDraw 事件上直接绘制到画布上 我正在绘制一些涉及单独绘制每个像素的东西 为此我使用类似的东西 for int x 0 x lt xMax x for int y 0 y lt
  • Java JDBC:更改表

    我希望对此表进行以下修改 添加 状态列 varchar 20 日期列 时间戳 我不确定该怎么做 String createTable Create table aircraft aircraftNumber int airLineCompa
  • 如何找到给定字符串的最长重复子串

    我是java新手 我被分配寻找字符串的最长子字符串 我在网上研究 似乎解决这个问题的好方法是实现后缀树 请告诉我如何做到这一点或者您是否有任何其他解决方案 请记住 这应该是在 Java 知识水平较低的情况下完成的 提前致谢 附 测试仪字符串
  • 制作一个交互式Windows服务

    我希望我的 Java 应用程序成为交互式 Windows 服务 用户登录时具有 GUI 的 Windows 服务 我搜索了这个 我发现这样做的方法是有两个程序 第一个是服务 第二个是 GUI 程序并使它们进行通信 服务将从 GUI 程序获取
  • 多个 Maven 配置文件激活多个 Spring 配置文件

    我想在 Maven 中构建一个环境 在其中我想根据哪些 Maven 配置文件处于活动状态来累积激活多个 spring 配置文件 目前我的 pom xml 的相关部分如下所示
  • JavaMail 只获取新邮件

    我想知道是否有一种方法可以在javamail中只获取新消息 例如 在初始加载时 获取收件箱中的所有消息并存储它们 然后 每当应用程序再次加载时 仅获取新消息 而不是再次重新加载它们 javamail 可以做到这一点吗 它是如何工作的 一些背
  • Spring @RequestMapping 带有可选参数

    我的控制器在请求映射中存在可选参数的问题 请查看下面的控制器 GetMapping produces MediaType APPLICATION JSON VALUE public ResponseEntity
  • 如何在PreferenceActivity中添加工具栏

    我已经使用首选项创建了应用程序设置 但我注意到 我的 PreferenceActivity 中没有工具栏 如何将工具栏添加到我的 PreferenceActivity 中 My code 我的 pref xml
  • 十进制到八进制的转换[重复]

    这个问题在这里已经有答案了 可能的重复 十进制转换错误 https stackoverflow com questions 13142977 decimal conversion error 我正在为一个类编写一个程序 并且在计算如何将八进
  • JRE 系统库 [WebSphere v6.1 JRE](未绑定)

    将项目导入 Eclipse 后 我的构建路径中出现以下错误 JRE System Library WebSphere v6 1 JRE unbound 谁知道怎么修它 右键单击项目 特性 gt Java 构建路径 gt 图书馆 gt JRE
  • 如何在控制器、服务和存储库模式中使用 DTO

    我正在遵循控制器 服务和存储库模式 我只是想知道 DTO 在哪里出现 控制器应该只接收 DTO 吗 我的理解是您不希望外界了解底层域模型 从领域模型到 DTO 的转换应该发生在控制器层还是服务层 在今天使用 Spring MVC 和交互式
  • 仅将 char[] 的一部分复制到 String 中

    我有一个数组 char ch 我的问题如下 如何将 ch 2 到 ch 7 的值合并到字符串中 我想在不循环 char 数组的情况下实现这一点 有什么建议么 感谢您花时间回答我的问题 Use new String value offset
  • Android 中麦克风的后台访问

    是否可以通过 Android 手机上的后台应用程序 服务 持续监控麦克风 我想做的一些想法 不断聆听背景中的声音信号 收到 有趣的 音频信号后 执行一些网络操作 如果前台应用程序需要的话 后台应用程序必须能够智能地放弃对麦克风的访问 除非可
  • 在mockito中使用when进行模拟ContextLoader.getCurrentWebApplicationContext()调用。我该怎么做?

    我试图在使用 mockito 时模拟 ContextLoader getCurrentWebApplicationContext 调用 但它无法模拟 here is my source code Mock org springframewo
  • Java列表的线程安全

    我有一个列表 它将在线程安全上下文或非线程安全上下文中使用 究竟会是哪一个 无法提前确定 在这种特殊情况下 每当列表进入非线程安全上下文时 我都会使用它来包装它 Collections synchronizedList 但如果不进入非线程安
  • 编译器抱怨“缺少返回语句”,即使不可能达到缺少返回语句的条件

    在下面的方法中 编译器抱怨缺少退货声明即使该方法只有一条路径 并且它包含一个return陈述 抑制错误需要另一个return陈述 public int foo if true return 5 鉴于Java编译器可以识别无限循环 https
  • 在 Maven 依赖项中指定 jar 和 test-jar 类型

    我有一个名为 commons 的项目 其中包含运行时和测试的常见内容 在主项目中 我添加了公共资源的依赖项
  • Firebase 添加新节点

    如何将这些节点放入用户节点中 并创建另一个节点来存储帖子 我的数据库参考 databaseReference child user getUid setValue userInformations 您需要使用以下代码 databaseRef
  • 有没有办法为Java的字符集名称添加别名

    我收到一个异常 埋藏在第 3 方库中 消息如下 java io UnsupportedEncodingException BIG 5 我认为发生这种情况是因为 Java 没有定义这个名称java nio charset Charset Ch

随机推荐

  • 将一个上下文中的 spring bean 替换为另一个上下文中的模拟版本

    我正在编写一个集成测试 其中应用程序上下文 xml 在启动期间初始化 测试类中有几个使用特定 bean X 已在 xml 中定义 的测试方法 我的实际要求是仅针对其中一种测试方法来模拟 bean X 在测试方法内部 我尝试使用 ClassP
  • GCP - 验证 PubSub 推送的云函数 https 端点的所有权

    很确定没有办法做到这一点 但很高兴联系看看其他人是否有任何想法 我想做的是 我有 2 个微服务作为云托管在 Google Cloud Platform 上 功能 我的第一个微服务执行任务并触发 PubSub 主题为 x 的消息 我想将我的第
  • 集合的位向量实现

    在阅读 aho 的数据结构书中有关集合基本操作的章节时 我在集合的位向量实现主题中遇到了以下行 if the universal set is sufficiently small so that a bit vector fits in
  • 如何缩小/剪切 Git 存储库

    我们有一个 Git 存储库 其中有 7 名贡献开发人员 拥有超过 2 5 年的历史和大约 10 000 次提交 我们使用 Assembla 进行推拉 当我们添加新的开发人员时 将存储库克隆到他们的开发计算机上需要将近一个小时 我不确定这是否
  • MySQL 触发器 - AFTER INSERT 触发器 + UDF sys_exec() 问题

    问题 我有一个保存某些记录的表 插入完成后 我想通过 MySQL 的 sys UDF 调用外部程序 php 脚本 现在 问题是我已将记录的 ID 传递给脚本的触发器 当我尝试通过脚本提取数据时 我得到 0 行 在我自己的测试中 我得出的结论
  • 为什么我的 Perl 就地脚本即使失败,也会以零退出代码退出?

    我有一个单行 Perl 搜索和替换 大致如下所示 perl p i e s foo bar non existent file txt 因为该文件不存在 这不是故意的 但这是自动构建脚本的一部分 所以我想防止这种情况发生 Perl 退出时出
  • 发布到 Facebook 后如何关闭弹出窗口?

    在我们的博客上 我们有一个链接 用户可以将我们的文章发布到他们的时间线 弹出窗口打开 用户向 Facebook 发帖 然后弹出窗口停留在那里并重定向到 www oursite com 当用户完成发布或单击取消按钮时 我们如何关闭弹出窗口 根
  • 使用 pip 安装软件包会返回错误[重复]

    这个问题在这里已经有答案了 不久前我从下载了 piphttps pip pypa io en stable installing 在我意识到我的 python 版本已经附带了 pip 之前 我成功地使用它来下载 pygame 但现在我尝试下
  • Swift 3:URLSession / URLRequest 不起作用

    我仍在尝试将我们的应用程序从 Swift 2 转换为 Swift 3 因为我们所有的 Apple 设备现在都运行 iOS 10 所以我被迫这样做 我已经完成了代码转换 并认为我做得很好 但是 在尝试调试我的 JSON 问题 发布在另一个问题
  • CodeIgniter:无法加载请求的文件:

    嗨 我是 codeigniter 的新手 我的网站可以在本地运行 但是当我上传时 出现以下错误 遇到错误 无法加载请求的文件 home home view php 这是我的控制器
  • Java 是否像 C++ 一样有未定义的行为?

    未定义的行为和序列点 上面的链接讨论的是C 中的序列点和副作用 简而言之 这意味着在两个序列点之间 如果我们有多个副作用 则副作用的顺序是未指定的 例如 int x 1 int y 2 int z x y 我们可以确定的是z等于3 之后z得
  • Matlab - 计算大稀疏(A'*A)矩阵的最大特征值

    我有一个大 400K 400K 稀疏矩阵 我需要计算的最大特征值A A 问题是由于内存问题 Matlab 甚至无法计算 A 我也尝试过 a b c find A 然后通过创建转置稀疏矩阵进行转置 但是尽管find 有效 但 sprase 创
  • 如何在 Windows 7 的登录屏幕上显示 UI

    我想在登录前屏幕 用户通常输入用户名 密码的屏幕 上显示与用户交互的 UI我读到 Winlogon 软件包的体系结构已更改 并且在 Windows 7 中对我没有帮助 有人建议我使用 WTS 功能 但我仍然不清楚如何使用它们或使用哪些功能
  • 如何使用 python 和 matplotlib 注释行尾?

    使用数据框和基本图 如下所示 import pandas as pd import numpy as np import matplotlib pyplot as plt np random seed 123456 rows 75 df p
  • 错误:View android.widget.ListView 不是滑动抽屉

    我在用NavigationDrawer在我的 Android 应用程序中 我也制作了自己的自定义布局 XML 文件及其适配器 但是当我运行我的程序时 我的应用程序崩溃并显示以下日志 我无法追踪其原因 有什么建议吗 活动主文件
  • 将序列链接到 hsqldb 中的标识

    在PostgreSql中 我们可以定义一个序列并将其用作表的主键 在 HsqlDB 中 我们仍然可以创建一个不链接到任何用户定义序列的自动增量标识列 是否可以使用用户定义的序列作为HsqlDB中自增标识列的生成器 PostgreSql 中的
  • Unity3D-获取组件

    在Unity3D中获取组件的最简单方法是什么C My case GameObject gamemaster C script MainGameLogic cs attached to gamemaster A boolean backfac
  • 编译器在运行前将 Java 字节码转换为与平台无关的 C 代码?

    我正在寻找一个编译器 可以在运行之前将 Java 字节码转换为独立于平台的 C 代码 提前编译 然后 我应该能够使用标准 C 编译器将 C 代码编译为目标平台的可执行文件 据我了解 这种方法仅适用于某些不经常修改的 Java 应用程序 那么
  • 如何在现代 C++ 中将 float 转换为 int

    尽管看起来很奇怪 但我找不到如何干净地转换float to an int 这种技术 int int value int float value 0 5 触发一个 warning use of old style cast in gcc 那么
  • Java中对象的内存消耗是多少?

    一个具有 100 个属性的对象所消耗的内存空间与 100 个对象 每个对象各有一个属性 所消耗的内存空间相同吗 为一个对象分配了多少内存 添加属性时使用了多少额外空间 Mindprod指出这不是一个容易回答的问题 JVM 可以自由地以任何内