Java中32位和64位系统的对象大小差异

 蒯曼荷学_936 发布于 2023-01-02 10:44

我遇到了一个面试问题:

class Test {
    int a ; 
    int b;
    char c;
}

这个类的内存对象将采用多少以及实现时的原因:

a)32位计算机

b)64位计算机

我的答案是:

For 32-bit: 4+4+2+8 = 18 bytes
For 64-bit: 4+4+2+16 = 26 bytes

由于分配了一些额外的内存,在32位系统中是8个字节,在64位系统中是16个字节,除了正常的对象大小.

你能否对这个陈述作出一些解释.

PS:我也想分享一个我从其他来源得到的答案(不能依赖,想要验证):

在32位pc对象占用比其数据成员定义的实际obj大小多8个字节.....并且在64位pc对象占用比其数据成员定义的实际对象大小多16个字节....现在问题出现了为什么会发生...其背后的原因据我所知是:::在32位pc中,前8个字节由JVM保留用于引用类定义,对齐,超类和子类的空间等.对于64位,它为这些保留16个字节.有一个公式用于计算对象在创建时需要多少堆空间,并计算为.......Shallow Heap Size = [对类定义的引用] +超类字段的空间+实例字段的空间+ [alignment]

你如何计算对象"本身"需要多少内存?显然有一个公式:

Shallow Heap Size = [对类定义的引用] +超类字段的空间+实例字段的空间+ [alignment]

似乎没有太大帮助,是吗?让我们尝试使用以下示例代码应用公式:

class X {
  int a;
  byte b;
  java.lang.Integer c = new java.lang.Integer();
}
class Y extends X {
  java.util.List d;
  java.util.Date e;
}

现在,我们努力回答的问题是 - Y的实例需要多少浅堆大小?假设我们使用的是32位x86架构,让我们开始计算它:

作为一个起点 - Y是X的子类,因此它的大小包括来自超类的"东西".因此,在计算Y的大小之前,我们考虑计算X的浅尺寸.

跳到X上的计算,前8个字节用于引用其类定义.此引用始终存在于所有Java对象中,并由JVM用于定义以下状态的内存布局.它还有三个实例变量 - 一个int,一个Integer和一个byte.这些实例变量需要堆如下:

它应该是一个字节.内存中有1个字节.我们的32位架构中的int需要4个字节.对Integer的引用也需要4个字节.注意,在计算保留堆时,我们还应该考虑包含在Integer对象中的原语的大小,但是由于我们在这里计算浅堆,我们在计算中只使用4个字节的引用大小.那么 - 就是这样吗?X = 8字节的浅堆从引用到类定义+ 1字节(字节)+ 4字节(int)+ 4字节(引用整数)= 17字节?事实上 - 没有.现在发挥作用的是对齐(也称为填充).这意味着JVM以8个字节的倍数分配内存,因此如果我们要创建X的实例,我们将分配24个字节而不是17个字节.

如果你可以关注我们,直到这里,好,但现在我们试图让事情变得更加复杂.我们不是创建X的实例,而是创建Y的实例.这意味着什么 - 我们可以从引用到类定义和对齐中扣除8个字节.它在第一时间可能不是太明显但是 - 你注意到在计算X的浅层大小时我们没有考虑到它也扩展了java.lang.Object,就像所有类都做的那样,即使你没有明确说明它你的源代码?我们不必考虑超类的头大小,因为JVM足够聪明,可以从类定义本身检查它,而不必一直将它复制到对象头中.

对齐也是如此 - 在创建对象时,您只对齐一次,而不是在超类/子类定义的边界.因此我们可以肯定地说,在创建X的子类时,您只会从实例变量继承9个字节.

最后,我们可以跳转到初始任务并开始计算Y的大小.正如我们所看到的,我们已经丢失了9个字节到超类字段.让我们看看当我们实际构造Y的实例时会添加什么.

引用其类定义的Y标头占用8个字节.与以前的相同.Date是对象的引用.4字节.简单.List是对集合的引用.再4个字节.不重要的.因此,除了来自超类的9个字节之外,我们还有来自头部的8个字节,来自两个引用的2×4个字节(列表和日期).Y实例的总浅层大小为25个字节,与32对齐.

撰写答案
今天,你开发时遇到什么问题呢?
立即提问
热门标签
PHP1.CN | 中国最专业的PHP中文社区 | PNG素材下载 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有