Answers:
简短的答案:是的,布尔值作为32位实体进行操作,但布尔数组每个元素使用1个字节。
更长的答案:JVM使用32位堆栈单元,用于保存局部变量,方法参数和表达式值。小于1个单元的基元被填充,大于32位(长和双精度)的基元占用2个单元。该技术可最大程度地减少操作码的数量,但确实有一些特殊的副作用(例如需要屏蔽字节)。
数组中存储的基元可能使用少于32位,并且有不同的操作码来加载和存储数组中的基元值。布尔值和字节值都使用baload
和bastore
操作码,这意味着布尔数组每个元素占用1个字节。
就内存中对象布局而言,这在“私有实现” 规则下已涉及到,它可以是1位,1字节,或者如另一个提示所指出的,与64位双字边界对齐。最有可能的是,它占用基础硬件的基本字长(32或64位)。
尽量减少布尔值使用的空间:对于大多数应用程序来说,这实际上不是问题。堆栈框架(包含局部变量和方法参数)不是很大,并且在大型方案中,对象中的离散布尔也不大。如果您有很多带有布尔值的对象,则可以使用通过getter和setter管理的位字段。但是,您将付出的CPU时间损失可能大于内存中的损失。
继承层次结构中某个地方的单个布尔值最多可以使用8个字节!这是由于填充。在Java对象使用多少内存中可以找到更多详细信息。:
回到布尔消耗多少的问题,是的,它确实消耗了至少一个字节,但是由于对齐规则,它可能消耗更多。恕我直言,更有趣的是知道boolean []每个条目将消耗一个字节而不是一位,并且由于对齐和数组的size字段而导致一些开销。在图算法中,大位字段很有用,并且需要注意的是,如果使用boolean [],则需要的内存几乎比实际需要的内存多8倍(1字节对1位)。
布尔映射是在考虑32位CPU的情况下完成的。int值具有32位,因此可以一次操作进行处理。
这是Peter Norvig的Java IAQ的一种解决方案:不常见问题,用于测量大小(有些不精确):
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.");