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

时间:2009-12-15 13:05:13

标签: java boolean

Java Virtual Machine Specification表示对布尔原始类型的支持有限。

  

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

以上暗示(虽然我可能误解了它)在操作布尔值时使用了int数据类型,但这是一个32位内存构造。假设布尔值仅代表1位信息:

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

8 个答案:

答案 0 :(得分:111)

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

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

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

就内存中的对象布局而言,这包含在“私有实现”rules下,它可以是1位,1个字节,或者作为另一个海报记录,与64位双精度对齐字边界。最有可能的是,它需要基础硬件的基本字大小(32或64位)。


尽量减少布尔使用的空间量:对于大多数应用来说,这确实不是问题。堆栈帧(保存局部变量和方法参数)不是很大,并且在大方案中,对象中的离散布尔值也不是那么大。如果你有很多带有大量布尔值的对象,那么你可以使用通过你的getter和setter管理的位字段。但是,您将在CPU时间内支付一个可能大于内存惩罚的惩罚。

答案 1 :(得分:7)

继承层次结构中的某个布尔值最多可以使用8个字节!这是由于填充。有关详细信息,请参阅How much memory is used by my Java object?

  

回到如何问题   很多布尔消耗,是的   消耗至少一个字节,但由于   对齐规则它可能消耗很多   更多。恕我直言,它更有趣   知道boolean []会消耗一个   每个条目的字节而不是一个位,加上   由于对齐而导致的一些开销   数组的大小字段。有   图形算法的大字段   位是有用的,你需要   意识到,如果你使用布尔[]你   几乎需要8倍   内存比真正需要的(1个字节   与1位)。

答案 2 :(得分:5)

第五版 Java in a Nutshell (O'Reilly)说布尔基元类型是1个字节。根据对堆的检查显示的内容,这可能是错误的。我想知道大多数JVM是否存在为变量分配少于一个字节的问题。

答案 3 :(得分:3)

布尔映射是在考虑32位CPU的情况下完成的。 int值有32位,因此可以在一次操作中处理。

以下是Peter Norvig's Java IAQ: Infrequently Answered Questions测量尺寸的解决方案(有些不精确):

static Runtime runtime = Runtime.getRuntime();
...
long start, end;
Object obj;
runtime.gc();
start = runtime.freememory();
obj = new Object(); // Or whatever you want to look at
end =  runtime.freememory();
System.out.println("That took " + (start-end) + " bytes.");

答案 4 :(得分:1)

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

此规范专用于32位CPU,因此可以使用其本机数据类型处理布尔值。

你只能在这里有一个:速度或记忆--SUN决定速度。

答案 5 :(得分:1)

布尔表示一点信息,但它的“大小”不是精确定义的,Sun Java教程说。布尔文字只有两个可能的值,即true和false。有关详细信息,请参阅Java Data Types

答案 6 :(得分:0)

我们无法确定布尔数据类型的确切大小。 它取决于虚拟机,或者在一个操作系统之间不同。

答案 7 :(得分:-10)

为什么不像这样制作一个.java文件:

Empty.java

class Empty{
}

和这样的一个类:

NotEmpty.java

class NotEmpty{
   boolean b;
}

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