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

2022-01-19 00:00:00 boolean java

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

The Java Virtual Machine Specification says that there is limited support for boolean primitive types.

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

There are no Java virtual machine instructions solely dedicated to operations on boolean values. Instead, expressions in the Java programming language that operate on boolean values are compiled to use values of the Java virtual machine int data type.

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

The above implies (although I may have misinterpreted it) that the int data type is used when operating on booleans, but this is a 32 bit memory construct. Given that a boolean only represents 1 bit of information:

  • 为什么不使用 byte 或 short 类型作为 boolean 而不是 int 的代理?
  • 对于任何给定的 JVM,什么是准确找出用于存储布尔类型的内存量的最可靠方法是什么?

推荐答案

简短回答:是的,布尔值作为 32 位实体进行操作,但布尔数组每个元素使用 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 个单元.这种技术最大限度地减少了操作码的数量,但确实有一些特殊的副作用(例如需要屏蔽字节).

Longer answer: the JVM uses a 32-bit stack cell, used to hold local variables, method arguments, and expression values. Primitives that are smaller than 1 cell are padded out, primitives larger than 32 bits (long and double) take 2 cells. This technique minimizes the number of opcodes, but does have some peculiar side-effects (such as the need to mask bytes).

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

Primitives stored in arrays may use less than 32 bits, and there are different opcodes to load and store primitive values from an array. Boolean and byte values both use the baload and bastore opcodes, which implies that boolean arrays take 1 byte per element.

就内存对象布局而言,这包含在私有实现"规则,它可以是 1 位、1 字节,或者如另一张海报所述,与 64 位双字边界对齐.最有可能的是,它采用底层硬件的基本字长(32 位或 64 位).

As far as in-memory object layout goes, this is covered under the "private implementation" rules, it can be 1 bit, 1 byte, or as another poster noted, aligned to a 64-bit double-word boundary. Most likely, it takes the basic word size of the underlying hardware (32 or 64 bits).

就最小化布尔值使用的空间量而言:对于大多数应用程序来说,这确实不是问题.堆栈帧(保存局部变量和方法参数)不是很大,并且在大方案中,对象中的离散布尔值也不是那么大.如果您有很多带有大量布尔值的对象,那么您可以使用通过 getter 和 setter 管理的位域.但是,您将在 CPU 时间上付出代价,这可能比在内存中的代价更大.

As far as minimizing the amount of space that booleans use: it really isn't an issue for most applications. Stack frames (holding local variables and method arguments) aren't very large, and in the big scheme a discrete boolean in an object isn't that large either. If you have lots of objects with lots of booleans, then you can use bit-fields that are managed via your getters and setters. However, you'll pay a penalty in CPU time that is probably bigger than the penalty in memory.

相关文章