为什么Java';s布尔基元大小未定义?

为什么Java';s布尔基元大小未定义?,java,boolean,Java,Boolean,声明对布尔基元类型的支持有限 没有专门用于布尔值操作的Java虚拟机指令。相反,Java编程语言中对布尔值进行操作的表达式被编译为使用Java虚拟机int数据类型的值 上面暗示(尽管我可能误解了)在布尔运算时使用int数据类型,但这是一个32位内存结构。假设布尔值仅表示1位信息: 为什么一个字节或短类型不被用作布尔值而不是int的代理 对于任何给定的JVM,最可靠的方法是什么来确定存储布尔类型所使用的内存量 布尔映射是在考虑32位CPU的情况下完成的。int值有32位,因此可以在一次操作中处理

声明对布尔基元类型的支持有限

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

上面暗示(尽管我可能误解了)在布尔运算时使用int数据类型,但这是一个32位内存结构。假设布尔值仅表示1位信息:

  • 为什么一个字节或短类型不被用作布尔值而不是int的代理
  • 对于任何给定的JVM,最可靠的方法是什么来确定存储布尔类型所使用的内存量
      布尔映射是在考虑32位CPU的情况下完成的。int值有32位,因此可以在一次操作中处理它

      这里有一个测量尺寸的解决方案(有一些不精确):


      继承层次结构中的某个布尔值最多可以使用8个字节!这是由于填充。有关更多详细信息,请参阅:

      回到怎么做的问题上来 是的,布尔运算消耗了很多 使用至少一个字节,但由于 对齐规则它可能会消耗很多 更多我觉得这更有趣 知道布尔[]将消耗一个 每个条目一个字节,而不是一位,加上 由于对齐和 数组的大小字段。有 图算法 比特是有用的,你需要 请注意,如果使用布尔值[],则 几乎需要8倍以上 内存超出实际需要(1字节 对1位)


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

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

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

      至于内存中的对象布局,这在“私有实现”中有所涉及,它可以是1位、1字节,或者如另一张海报所述,与64位双字边界对齐。最有可能的是,它采用底层硬件的基本字大小(32或64位)



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

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

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


      这里只能有一个:速度或内存-SUN决定速度。

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

      Empty.java

      class Empty{
      }
      
      class NotEmpty{
         boolean b;
      }
      
      还有一类是这样的:

      NotEmpty.java

      class Empty{
      }
      
      class NotEmpty{
         boolean b;
      }
      

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

      Java第五版简而言之(O'Reilly)说布尔基元类型是1字节。根据堆的检查结果,这可能是错误的。我想知道大多数JVM在为变量分配少于一个字节时是否存在问题。

      我们无法确定布尔数据类型的确切大小它依赖于虚拟机,或者因操作系统而异。

      如何使用布尔[]?布尔[]可以用作掩码。但有时位集可能会更好,因为它有一些有用的方法。这是另一个度量,与内存中基本布尔类型的大小无关。对于布尔/字节类成员,它们也是4字节,这也是真的吗?类实例在堆栈上作为一个整体进行分配,因此我可以想象,JVM可能应该为每个布尔/字节成员使用1个字节,并最终为完整的类实例进行4字节对齐。是这样吗?(如果你有证明这一点的引用,请分享)@dma_k:正如我在回答中所指出的,类实例的布局依赖于实现。但是,请注意,类实例并不存储在堆栈中,而是存储在堆中(尽管您会看到一些对JDK 7“escape analysis”的引用将对象从一个堆栈移动到另一个堆栈,但情况似乎并非如此;请参见java.sun.com/javase/7/docs/technotes/guides/vm/…),有时候打包布尔值实际上可能更快。每当缓存大小重要时,最好打包东西。例如,分段的主筛在32KB(一级缓存大小)的块中工作要比非分段筛快得多。块之间有一些开销,打包时你支付开销的次数减少了八倍。我还没有对它进行测量。因为这个对话是关于原语的,所以在测试它时你必须有创造性,因为原语不存储在堆中,除非它们是实例或数组上的字段。两个都不是