为什么 Java 的布尔基元大小没有定义?

2022-08-31 09:18:52

Java 虚拟机规范指出,对布尔基元类型的支持有限。

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

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

  • 为什么字节或短类型不用作布尔值而不是 int 的代理?
  • 对于任何给定的JVM,找出究竟有多少内存用于存储布尔类型的最可靠的方法是什么?

答案 1

简短的回答:是的,布尔值作为32位实体,但布尔数组每个元素使用1个字节。

更长的答案:JVM使用32位堆栈单元,用于保存局部变量,方法参数和表达式值。小于 1 个单元格的基元被填充掉,大于 32 位(长和双)的基元需要 2 个单元格。这种技术最大限度地减少了操作码的数量,但确实有一些特殊的副作用(例如需要屏蔽字节)。

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

就内存中对象布局而言,这在“私有实现”规则中有所涵盖,它可以是1位,1字节,也可以是另一个海报所指出的,与64位双字边界对齐。最有可能的是,它需要底层硬件的基本字大小(32 或 64 位)。


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


答案 2

继承层次结构中某处的单个布尔值最多可以使用 8 个字节!这是由于填充。有关更多详细信息,请参阅我的 Java 对象使用了多少内存?

回到布尔值消耗多少的问题,是的,它确实消耗了至少一个字节,但由于对齐规则,它可能会消耗更多。恕我直言,更有趣的是,布尔值[]将消耗每个条目一个字节而不是一个位,再加上由于对齐和数组的大小字段而产生的一些开销。在一些图形算法中,大字段的位是有用的,你需要意识到,如果你使用布尔值[],你需要的内存几乎是实际需要的8倍(1个字节与1个位)。