为什么没有定义 Java 的布尔原语大小?

Java 虚拟机规范表示对布尔 原始类型的支持有限。

不存在专门用于对布尔值进行操作的 Java 虚拟机指令。相反,Java 编程语言中操作布尔值的表达式被编译为使用 Java 虚拟机 int 数据类型的值。

上面暗示(尽管我可能误解了它)在对布尔值进行操作时使用 int 数据类型,但这是一个32位内存结构。假设布尔值只代表1位信息:

  • 为什么一个字节或者短的类型不用作布尔值的代理,而是用作整型数?
  • 对于任何给定的 JVM,找出用于存储布尔类型的确切内存使用量的最可靠方法是什么?
61164 次浏览

在继承层次结构中的某个地方,一个布尔值最多可以使用8个字节!这是由于填充物。详情请参阅 How much memory is used by my Java object?:

回到如何 布尔值消耗了很多,是的 至少消耗一个字节,但由于 alignment rules it may consume much 更多。恕我直言,更有趣的是 知道布尔型[]会消耗一个 每个条目的字节,而不是一个位,加号 some overhead due to alignment and for 数组的 size 字段 graph algorithms where large fields of 比特是有用的,你需要 注意,如果你使用布尔型[] 需要几乎正好8倍以上 内存超过实际需要(1字节 对比1位)。

Short answer: yes, boolean values are manipulated as 32-bit entities, but arrays of booleans use 1 byte per element.

更详细的答案: JVM 使用32位堆栈单元,用于保存本地变量、方法参数和表达式值。填充小于1个单元的基元,大于32位(长和双)的基元占用2个单元。这种技术尽量减少操作码的数量,但是确实有一些特殊的副作用(比如需要屏蔽字节)。

存储在数组中的基元可以使用少于32位,并且有不同的操作码来加载和存储来自数组的基元值。布尔值和字节值都使用 baloadbastore操作码,这意味着布尔数组每个元素占用1个字节。

至于内存中的对象布局,这是涵盖在“私有实现”规矩,它可以是1位,1字节,或作为另一张海报指出,对齐到64位双字边界。最有可能的是,它采用底层硬件的基本字大小(32或64位)。


至于最小化布尔值使用的空间量: 对于大多数应用程序来说,这真的不是一个问题。堆栈框架(包含局部变量和方法参数)不是很大,在大的方案中,对象中的离散布尔值也不是很大。如果您有很多带有很多布尔值的对象,那么您可以使用通过 getter 和 setter 管理的位字段。但是,您将在 CPU 时间上付出的代价可能大于内存中的代价。

CPU 在特定的数据类型长度上运行。对于32位 CPU,它们是32位长的,因此在 Java 中称为“ int”。所有低于或高于这个长度的内容都必须填充或分割到这个长度,然后 CPU 才能处理它。这不会花费太多时间,但是如果基本操作需要2个 CPU 周期而不是1个,这意味着成本/时间翻倍。

这个规范专门用于32位 CPU,这样它们就可以用自己的本机数据类型处理布尔值。

You can only have one here: speed or memory - SUN decided for speed.

为什么不像下面这样创建一个.java 文件:

爪哇空空

class Empty{
}

还有这样一门课:

NotEmpty.java

class NotEmpty{
boolean b;
}

将它们都编译,并将. class 文件与十六进制编辑器进行比较。

果壳中的爪哇的第5版(O’Reilly)表示布尔原语类型为1字节。根据堆的检查结果,这可能是错误的。我想知道大多数 JVM 在为变量分配少于一个字节时是否存在问题。

我们不能说出布尔数据类型的确切大小