如何计算Java数组的内存大小?

2024-04-27

我知道如何通过添加三个部分来计算Java对象的内存大小:标头+属性+引用。

我还知道Java数组也是一个对象。

但是当我读到《Understanding the JVM Advanced Features and Best Practices, Second Edition》时,它说Java数组的头部由三部分组成;标记字、类指针和数组长度。

在 Hotspot 64 位 JVM 中它始终是 24 字节。

但是在32位JVM中,如何计算Java数组的内存大小呢?

我希望你们能给我一些 Java 代码示例来告诉我如何计算对象的内存大小,而不限于数组对象。


实际的对象大小是特定于实现的,甚至不要求对象所需的大小在其生命周期内保持不变。

There’s wiki.openjdk.java.net 上的一篇文章 https://wiki.openjdk.java.net/display/HotSpot/CompressedOops#CompressedOops-Objectheaderlayout陈述:

对象标题布局

对象头由一个本机大小的标记字、一个 klass 字、一个 32 位长度字(如果对象是数组)、一个 32 位间隙(如果对齐规则需要)以及零个或多个实例组成字段、数组元素或元数据字段。 (有趣的琐事:Klass 元对象在 klass 单词之后立即包含一个 C++ vtable。)

间隙字段(如果存在)通常可用于存储实例字段。

如果 UseCompressedOops 为 false(并且始终在 ILP32 系统上),则 mark 和 klass 都是本机机器字。对于阵列,间隙始终存在于 LP64 系统上,并且仅存在于 ILP32 系统上具有 64 位元素的阵列上。

如果 UseCompressedOops 为 true,则 klass 为 32 位。非数组在 klass 后面紧接着有一个间隙字段,而数组在 klass 后面紧接着存储长度字段。

您计算对象大小的“标题+属性+引用”不正确。首先,对对象的引用不属于引用对象的对象大小。可以有任意数量的对同一对象的引用,但这些引用根本不必位于堆内存或 RAM 中,因为优化的代码可以纯粹通过 CPU 寄存器访问对象。

此外,正如上面引用中所暗示的,对齐规则使得字段所需的内存计算变得非常重要。标头中可能存在一个间隙,如果存在适合其中的类型的字段,则该间隙可用于存储实例字段。虽然同一类的字段可能会进行排列以最小化填充,但子类必须适应超类的布局,可能会向其中添加更多字段,并且只有在具有适合类型的字段时才可能填充空白,否则,由于类层次结构的原因,可能会有更多的差距。

对于数组,您可以从引用的文章中得出,32 位 HotSpot 表示使用 12 字节的标头,除非类型是long[] or double[],在这种情况下它将是 16 字节。

对于 64 位实现,UseCompressedOops选项(默认情况下处于启用状态)允许将 64 位标记字与 32 位 klass 和 32 位长度组合到总共 16 字节的标头中。除非UseCompressedOops关闭时,标头将为 24 字节。

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

如何计算Java数组的内存大小? 的相关文章

随机推荐

  • Hibernate - 一对多关系和孤儿删除级联

    我有一个基本的一对多关系父 子关系 就像 Hibernate 参考书第 21 章中一样 级联仅从子级到父级 保留级联只是因为我不想在删除子级时删除父级 当我向父级添加一个子级并保存该子级时 出现 TransientObjectExcepti
  • 上下文保留评估

    我们正在构建一个小型 REPL 来评估 使用eval 用户输入的 JavaScript 表达式 由于整个事情是事件驱动的 因此评估必须在单独的函数中进行 但必须在调用之间保留上下文 即所有声明的变量和函数 我想出了以下解决方案 functi
  • 在 Jekyll 中,如何更改将文件名转换为博客文章标题的大小写规则?

    我正在尝试更改 Jekyll 中博客文章标题的大小写 而不必每次都在 yaml 标题字段中键入它 默认情况下 jekyll 转换文件2016 02 22 my blog title标题 我的博客标题 我希望它是 我的博客标题 我注意到我可以
  • 如何使用 ASP classic 进行重定向

    我想从一个 URL 重定向到另一个 URL http female deals com http male deals com 如何通过在浏览器中将 URL 更改为新 URL 以及页面直接转到新 URL 而无需转到旧 URL 并进行刷新来实
  • Py2Exe“缺少以下模块”

    使用 Py2Exe 时 我收到警告 例如 The following modules appear to be missing Crypto Crypto Cipher Crypto Hash Padding 由于找不到这些模块 导致 EX
  • 使用嵌套 C++ 类和枚举的优点和缺点?

    使用嵌套公共 C 类和枚举的优点和缺点是什么 例如 假设您有一个名为printer 并且此类还存储输出托盘上的信息 您可以 class printer public std string name enum TYPE TYPE LOCAL
  • 同一服务器,SSL 和非 SSL

    Apache 2 x 中是否可以在同一服务器上同时运行 SSL 协议和非 SSL 协议 所以如果我访问http example com 非 SSL 和https example com SSL 它们都可用 如果是这样 我需要创建一个虚拟主机
  • DirectX 世界视图矩阵乘法 - GPU 或 CPU 的地方

    我是 directx 的新手 但令我惊讶的是 我看到的大多数示例中 世界矩阵和视图矩阵都是作为顶点着色器的一部分相乘 而不是与 CPU 相乘并将结果传递给着色器 对于刚性对象 这意味着您为对象的每个顶点将相同的两个矩阵相乘一次 我知道 GP
  • 是否有针对非视网膜显示的媒体查询?

    根据关于 CSS 技巧的文章 https css tricks com snippets css retina display media query 面向未来的视网膜显示媒体查询可以写为 media only screen and web
  • 如何将 JMX 绑定到特定接口?

    我目前正在启动我的 Java VMcom sun management jmxremote 属性 以便我可以通过 JConsole 连接到它进行管理和监控 不幸的是 它监听机器上的所有接口 IP 地址 在我们的环境中 经常会出现多个 Jav
  • 处理 Javascript 中的浮点精度[重复]

    这个问题在这里已经有答案了 我有大量数值y在 JavaScript 中 我想通过将它们四舍五入到最接近的倍数来对它们进行分组x并将结果转换为字符串 如何解决烦人的浮点精度 例如 0 2 0 4 0 6000000000000001 我尝试过
  • 解析嵌套的 JSON Swift 3 [重复]

    这个问题在这里已经有答案了 我正在尝试在 Swift 3 中解析复杂的 JSON 文件 我在获取值时遇到问题 我找到了一些示例代码并尝试对其进行了一些调整 但它不起作用我当前收到错误 Type NSArray 没有下标成员 我什至不确定这是
  • WebStorm/PHPStorm 中的智能选项卡有什么作用?

    我对智能选项卡在一般偏好中的作用感到困惑 它说 仅通过空格即可对必要的列进行精细对齐 如果 如果未选中此复选框 则使用空格进行对齐 必要的 这是否意味着在这两种情况下都使用空格来对齐 这是否意味着它总是在后者中使用空格 而仅有时在前者中使用
  • 如何根据功能(自动)通过属性查看或隐藏字段?

    我只想查看员工 他的经理和 hr group hr user 组的 working hours 字段 如何隐藏该字段自动执行 无需编辑表单或触发按钮 class InheritHrEmployee models Model inherit
  • Grails“max”带有关联的子查询,仅获取最新的 hasMany

    简化的域模型 Txn 如交易中 有许多 TxnStatus TxnStatus 有一个日期时间 这是一个遗留映射 所以我无法更改 DB Txn 上的映射 static mapping txnStatus column MessageID i
  • JavaScript 运行时错误:无法获取未定义或空引用的属性“msie”

    我只是尝试更改我的 jquery ui 对母版页的引用 我仅在 Internet Explorer 上收到上述错误 我在 Firefox 和 Chrome 上没有收到错误消息 这是抛出错误的 jquery 代码 return a brows
  • 仅横向应用程序中的 GameCenter 身份验证抛出 UIApplicationInvalidInterfaceOrientation

    问题 如果用户未登录 GameCenter 帐户 GameCenter 身份验证视图以纵向模式启动 在 ios 5 中 有一个模式对话框 要求登录 但是如果我在 xcode 项目摘要 或supportedInterfaceOrientati
  • 根据使用频率随机生成字母?

    如何根据常用语音中的使用频率随机生成字母 任何伪代码都值得赞赏 但如果用 Java 实现就更棒了 否则 只需朝正确的方向戳一下就会有所帮助 注意 我不需要生成使用频率 我确信我可以很容易地查找到它 我假设您将频率存储为 0 到 1 之间的浮
  • 使用IntelliJ编译Java 7,配置麻烦

    我正在使用 IntelliJ 并尝试让它与 Java 7 一起工作 我的 JDK 设置为指向最新的 JDK 此外 项目也设置使用它 然而 当尝试编写 Java7 代码时 它的语法无法被识别 请问我缺少什么 Set the 项目语言水平 to
  • 如何计算Java数组的内存大小?

    我知道如何通过添加三个部分来计算Java对象的内存大小 标头 属性 引用 我还知道Java数组也是一个对象 但是当我读到 Understanding the JVM Advanced Features and Best Practices