问题描述
Java 虚拟机规范 表示对布尔原始类型的支持有限.
The Java Virtual Machine Specification says that there is limited support for boolean primitive types.
没有专用于布尔值运算的 Java 虚拟机指令.相反,Java 编程语言中对布尔值进行操作的表达式被编译为使用 Java 虚拟机 int 数据类型的值.
以上暗示(尽管我可能误解了它)在对布尔值进行操作时使用 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:
- 为什么不使用字节或短类型作为布尔值而不是 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 位,并且有不同的操作码可以从数组加载和存储基元值.布尔值和字节值都使用 baload
和 bastore
操作码,这意味着布尔数组每个元素占用 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.
这篇关于为什么未定义 Java 的布尔基元大小?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!