Java 字节是否比布尔值[8]更有效
如果我在一个类中需要8个布尔成员变量,Java是否有效地将它们全部放在一个字节中?或者它会为每个字节使用一个字节?换句话说,以下各项的内存占用是否有所不同:Java 字节是否比布尔值[8]更有效,java,Java,如果我在一个类中需要8个布尔成员变量,Java是否有效地将它们全部放在一个字节中?或者它会为每个字节使用一个字节?换句话说,以下各项的内存占用是否有所不同: boolean a; boolean b; boolean c; boolean d; boolean e; boolean f; boolean g; boolean h; vs 我之所以这样问,是因为我将实例化一批这些对象。因此,让它占用1字节而不是8字节的内存将是一个明显的节约 更新:这绝对类似于将布尔值存储在int中的链接问题列表
boolean a;
boolean b;
boolean c;
boolean d;
boolean e;
boolean f;
boolean g;
boolean h;
vs
我之所以这样问,是因为我将实例化一批这些对象。因此,让它占用1字节而不是8字节的内存将是一个明显的节约
更新:这绝对类似于将布尔值存储在int中的链接问题列表(感谢您提供这些链接,很抱歉我在询问之前没有找到它们)。这个问题有点不同,因为它提供了使用字节和位标志的具体替代方案。我不知道这是否足以使这个问题不再重复
更新2:我刚刚使用运行了这个,发现了以下内容。8个布尔值需要24字节/对象或3字节/布尔值。单字节方法需要10字节/对象。我可以理解8,它将字节扩展为本机int(我在64位系统上)。但是其他两个字节是什么呢?在Java中,布尔值表示的实际信息是一位:1表示真,0表示假。然而,Java规范并没有精确定义内存中布尔变量的实际大小 布尔数据类型只有两个可能的值:true和false。 将此数据类型用于跟踪真/假条件的简单标志。 此数据类型表示一位信息,但其“大小” 不是精确定义的东西
因此,如果要创建大量布尔值,最好使用
byte
。取决于VM如何在内存中实现字段
但根据常识,在对象中,每个字段都位于自己的内存槽中,实现起来要容易得多,而且它的大小也取决于VM,可以是一个字节或更大的值(我猜是int)
您可以通过创建一个包含大量这些对象(比如10M)的数组,并检查使用了多少内存(例如运行时API),来衡量特定VM的这一点
但我只会在我有严重的记忆问题时才担心这个问题。使用布尔函数,您可以在真正需要的时候将其重新实现为标志字段(前提是您不使用直接字段访问和getter来乱扔代码)。阅读本主题。他们建议将其作为大型布尔对象集的解决方案,但在您的情况下,byte
可以更好地解决问题,因为您不会有大型布尔对象集,而是会有大型的8个布尔对象集
总结:字节优于8布尔值。如果你看看JDK 8的性能,它们仍然使用位掩码,我能想到的唯一原因是内存效率:
public static final int DISTINCT = 0x00000001;
public static final int SORTED = 0x00000004;
public static final int ORDERED = 0x00000010;
public static final int SIZED = 0x00000040;
所以这应该是一个很好的方法。我打赌在64位机器上,它会将它们分开8个“是”。但这取决于JVM。在内存方面是浪费的,但在性能方面不是。是的,它更有效由于不言而喻的原因,
boolean
必须是保存boolean以满足通常要求的最佳数据结构;否则会使用其他的东西。我有一种感觉,通常的要求可能是以牺牲内存为代价的访问速度。您想牺牲访问速度吗?就JLS的定义而言,Boolean只是最好的类型。就速度而言,boolean在VM的实现中有一些怪癖,这使得它可能比出于相同目的(使用C风格的non-zero==TRUE)取消整整数的速度要慢。boolean的问题在于,它们几乎不可避免地需要引入分支到代码中的字节码(例如,实现“boolean b=x==y”,其中c风格可以说“int b=x-y”)。你可以用javap来检查这一点,除非他想出了一种方法来划分一个位集,这样它就可以在数百个对象之间共享,这8个布尔字段。。。每个对象可以有一个索引号n
,并在8个布尔值的共享位集中使用字段8*n
到8*n+7
。这可能比您真正想要处理的更混乱。@dcsohl它在内存使用方面的结果几乎相同,所以我认为使用byte会更好。正如Andrey answer所示,在JDK中,它们也使用掩码存储布尔值。附加信息:@dcsohl共享位集需要某种形式的引用,引用占用的内存至少与字节占用的内存相同。不是一个实际的想法。是的,你是对的。那么好吧。我会等到JDK 8最终确定之后再推荐它的“实现…”。。。
public static final int DISTINCT = 0x00000001;
public static final int SORTED = 0x00000004;
public static final int ORDERED = 0x00000010;
public static final int SIZED = 0x00000040;