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

Java虚拟机规范说,对布尔基types的支持有限。

没有专用于布尔值操作的Java虚拟机指令。 相反,Java编程语言中操作布尔值的expression式被编译为使用Java虚拟机int数据types的值。

上面的意思是(虽然我可能误解了它)int数据types是在布尔操作时使用的,但是这是一个32位的内存构造。 假设一个布尔值只代表1位信息:

  • 为什么一个字节或短的types不用作布尔代替int的代理?
  • 对于任何给定的JVM,确切地找出用于存储布尔types的内存的最可靠的方法是什么?

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

较长的回答:JVM使用一个32位堆栈单元,用于存放局部variables,方法参数和expression式值。 小于1单元的基元被填充,大于32位的基元(长和双)取2个单元。 这种技术可以最小化操作码的数量,但确实有一些特殊的副作用(例如需要屏蔽字节)。

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

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


至于尽量减less布尔的使用空间:对于大多数应用程序来说,这确实不成问题。 堆栈帧(包含局部variables和方法参数)不是很大,在大的scheme中,对象中的离散布尔值也不是那么大。 如果你有很多布尔对象的对象,那么你可以使用通过你的getter和setter来pipe理的位域。 但是,您将在CPU时间内支付罚款,可能大于内存中的罚款。

inheritance层次结构中的某个布尔值最多可以使用8个字节! 这是由于填充。 更多细节可以在我的Java对象使用多less内存中find? :

回到布尔值消耗多less的问题上,是的,它至less消耗了一个字节,但是由于alignment规则,它可能消耗更多。 恕我直言,这是更有趣的知道,布尔[]将消耗每个条目一个字节,而不是一个位,加上一些开销,由于alignment和arrays的大小字段。 有一些图表algorithm,其中大量的位是有用的,你需要知道的是,如果你使用布尔[],你需要的内存几乎是真正需要的8倍(1字节与1位)。

在一个简单Java (O'Reilly)第五版中说,一个布尔基本types是1位。 这可能是错误的,根据堆的检查显示。 我想知道是否大多数JVM在为variables分配less于一个字节方面有问题。

布尔映射是用32位CPU完成的。 int值有32位,所以可以在一个操作中处理。

下面是Peter Norvig的Java IAQ的一个解决scheme:测量大小的不常见的问题 (有些不精确):

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."); 

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

该规范专用于32位CPU,以便他们可以使用本机数据types处理布尔值。

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

布尔表示一个信息位,但是它的“大小”并不是精确定义的东西,比如说Sun的Java教程。 布尔文字只有两个可能的值,即真和假。 详情请参阅Java数据types 。

为什么不能像这样创build一个.java文件:

Empty.java

 class Empty{ } 

和一个这样的class级:

NotEmpty.java

 class NotEmpty{ boolean b; } 

将它们编译并使用hex编辑器比较.class文件。