2013-11-26 40 views
2

Oracle website上,它表示bools在堆栈中占用32位,而在数组中占8位。我很难理解为什么他们在一个小组中比在单身时少。它们是如何存储的,它们有什么不同?如果布尔数组更有效率,为什么这项技术不会转移到单身?为什么bools在阵列中占用较少的内存?

另外,为什么不1位?

64位系统和32位系统如何存储这些数据有什么区别?

谢谢!

+0

与问题无关,但请阅读以下内容:http://meta.stackexchange.com/questions/27162/ethics-of-editing-out-gratitude – alfasin

+0

感谢您的链接,@alfasin以及感谢您关注以下问题规则...我把我的感激回馈,因为我真的很感谢这个真棒网站,我感觉像是一个'谢谢!'真的不会妨碍任何理解。它有点说:“我是一个真正的人,我很感激你支付我的一些注意!” –

回答

3

看起来,当谈到堆栈时,必须记住速度是最重要的。例如,考虑以下因素:

void method(int foo, boolean bar, String name) .... 

然后堆栈刚过进入方法是这样的:

|-other variables-|-...-|-name-|-bar-|-foo-|---- return address etc. -- 
^ 
stack pointer 

这些都是一个字边界上的所有数量,由|象征。当然,JVM可以(理论上,但见下文)将布尔值存储在单个字节中。但是我们必须记住,32位负载在不处理字边界时可能会变慢。根据体系结构,可能不可能通过一个不在字边界上的指针。或者可能无法在浮点指令中使用数量等。

另外,字节码格式只能寻址堆栈中第012个字。如果不是这样,相对于堆栈指针的地址必须以字节指定,这意味着几乎任何堆栈访问都会有两个大部分时间无关的位,因为大多数参数都是字(int ,浮点或引用)或双字(长,双)。

从来没有可能的是使用1位布尔值。为什么?因为位不能直接寻址。最小的可寻址单元是字节。

如果您觉得应该节省内存,则仍然可以在int中存储32个布尔值。

3

由于CPU工作的方式,所有的操作都以32位完成。如果你有一个单一的bool,编译器可以做的唯一现实的事情是将其余的24位清零并保存到堆栈中,因为扫描你的java文件以供其他bools使用并将它们全部存储在相同的32位内存块。

如果你有一个布尔数组,只需要以4个块为单位来引用它们是很简单的,所以它只有8个布尔值。

请注意,这仅适用于32位应用程序/机器。

+1

我的后续问题是,为什么不使用1位bool并将它们存储在32个块中?那会更有效率,不是吗? – CompuChip

+1

好吧,对此的回答是,jvm并不是为支持1位操作而构建的,所以“bool”只是一个以另一个名字命名的字节。使用1位保存的内存量非常小,不值得增加计算复杂度。 –

+1

如果他们将bools存储到一个位中,可能会涉及更多的开销,因为今天的CPU并不是为了获取单个内存而设计的。 – Josh

7

一个布尔值可以存储为一个二进制数字,但我们的计算机组值为方便。实际处理的最小单位是一个字节,其次是一个字。在现代硬件中,一个字节总是8位。 32位已经成为一个词的标准。即使我们的64位计算机也能有效处理32位字。将bool存储在任何自然单元中比单独存储要方便得多。在一个数组中,自然单位将是一个字节,因为您可以处理内存中的任何字节。在字堆栈中,自然单元是一个字。你可以将bools填入字节和单词中,并逐字逐句地将它们一点一点地拉出来,但这比将它们存储在字节或单词中效率不高,因为现代存储器很大,所以CPU速度更受关注。你不想浪费所有的时间来紧凑地打包比特,所以我们浪费了内存,因为它更加易耗。

+0

这就是我正在寻找的。还有一件事...... 64位机器有没有不同的存储方式? –

+0

我们的64位x64体系结构基于较旧的32位x86体系结构,并且在不需要64位时通常处理32位。给我一点时间来看看x64以确定调用堆栈是否总是64位,我会马上回到你身边。 –

+0

在x64架构中,堆栈将始终为64位。当一个64位CPU运行一个32位程序时,它将64位字段中的所有32位值存储在堆栈中,因此浪费了一半的存储空间。 bool将作为64位字存储在x64计算机的堆栈中。 –