首页 文章

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

提问于
浏览
105

Java Virtual Machine Specification表示对布尔 primitive 类型的支持有限 .

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

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

  • 为什么一个byte或short类型没有用作布尔值而不是int的代理?

  • 对于任何给定的JVM,找出用于存储布尔类型的确切内存的最可靠方法是什么?

7 回答

  • 1

    继承层次结构中的某个布尔值最多可以使用8个字节!这是由于填充 . 更多细节可以在How much memory is used by my Java object?找到:

    回到布尔消耗多少的问题,是的,它确实消耗了至少一个字节,但由于对齐规则,它可能消耗更多 . 恕我直言,更有意思的是,boolean []将消耗每个条目一个字节而不是一个比特,加上由于对齐和数组大小字段的一些开销 . 有大量的位字段是有用的图形算法,您需要注意,如果使用布尔值[],您需要的内存几乎是实际需要的8倍(1个字节对1位) .

  • -10

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

  • 3

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

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

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

    就内存中的对象布局而言,这包含在"private implementation" rules中,它可以是1位,1字节,或者作为另一张海报,与64位双字边界对齐 . 最有可能的是,它需要基础硬件的基本字大小(32或64位) .


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

  • 7

    布尔映射是在考虑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.");
    
  • 5

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

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

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

  • 107

    Sun Java教程说,布尔表示一位信息,但它的"size"是精确定义的 . 布尔文字只有两个可能的值,即true和false . 有关详细信息,请参阅Java Data Types .

  • 1

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

    Empty.java

    class Empty{
    }
    

    和这样一个类:

    NotEmpty.java

    class NotEmpty{
       boolean b;
    }
    

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

相关问题