【问题标题】:Why do bools take less memory in an array?为什么布尔在数组中占用更少的内存?
【发布时间】:2013-12-12 03:49:15
【问题描述】:

Oracle website 上,它表示布尔值在堆栈中占用 32 位,但在数组中占用 8 位。我很难理解为什么他们在一个团体中比在单人中要少。它们是如何存储的,有什么区别?如果 bool 数组更有效,为什么没有将这项技术转移到 singles 上?

另外,为什么不是 1 位?

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

谢谢!

【问题讨论】:

  • 与问题无关,但请阅读:meta.stackexchange.com/questions/27162/…
  • 感谢您的链接,@alfasin,感谢您遵守规则...我再次表示感谢,因为我真的很感谢这个很棒的网站,我觉得“谢谢!”真的不会妨碍任何理解。它有点像“我是一个真实的人,我很感激你关注我的帖子!”

标签: java arrays memory memory-management boolean


【解决方案1】:

布尔值可以存储为单个二进制数字,但我们的计算机将值分组为方便起见。实际处理的最小单位是字节,其次是字。在现代硬件中,一个字节总是 8 位。 32 位已成为一个字的标准。即使是我们的 64 位计算机也可以有效地处理 32 位字。将 bool 存储在任何自然出现的单元中比存储一个位要方便得多。在数组中,自然单位是字节,因为您可以寻址内存中的任何字节。在栈上,也就是字栈,自然单位就是一个字。您可以将布尔值填充到字节和字中,然后将它们一点一点地再次取出,但这比将它们存储在字节或字中效率低,因为现代内存很大,因此 CPU 速度更值得关注。你不想浪费所有时间来紧凑地打包比特,所以我们浪费了内存,因为它更易消耗。

【讨论】:

  • 这就是我想要的。不过还有一件事...... 64 位机器存储它有什么不同吗?
  • 我们的 64 位 x64 架构基于较旧的 32 位 x86 架构,并且在不需要 64 位时通常会处理 32 位。给我一点时间看看 x64 以确定调用堆栈是否总是 64 位,我会尽快回复你。
  • 在 x64 架构中,堆栈将始终为 64 位。当 64 位 CPU 运行 32 位程序时,它会将所有 32 位值存储在堆栈上的 64 位字段中,因此浪费了一半的存储空间。 bool 将作为 64 位字存储在 x64 计算机的堆栈中。
【解决方案2】:

看,当谈到堆栈时,必须牢记速度是最重要的。例如,考虑以下情况:

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

那么刚进入方法后的栈是这样的:

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

这些都是单词边界上的数量,用| 表示。当然,JVM 可以(理论上,但见下文)将布尔值存储在单个字节中。但是必须记住,当 32 位加载不解决字边界时,它们可能会更慢。根据体系结构,可能无法通过不在字边界上的指针。或者可能无法在浮点指令等中使用数量。

此外,字节码格式只能寻址堆栈上的第 n 个字。如果不是这样,则必须以字节为单位指定与堆栈指针相关的地址,这意味着几乎任何堆栈访问都会有两个大多数时间不相关的位,因为大多数参数将是字(int , float 或 reference) 或双字 (long, double)。

永远不可能将 1 位用于布尔值。为什么?因为位不能直接寻址。最小的可寻址单元是字节。

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

【讨论】:

    【解决方案3】:

    由于 CPU 的工作方式,所有操作都以 32 位完成。如果你有一个布尔值,编译器唯一能做的就是将剩下的 24 位清零并将其保存到堆栈中,因为扫描你的 java 文件中的其他布尔值并将它们全部存储在相同的 32 位内存块。

    如果您有一个布尔数组,只需以 4 块为单位引用它们很简单,因此每个布尔只有 8 位。

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

    【讨论】:

    • 我的后续问题是,为什么不使用每个布尔值 1 位并将它们存储在 32 块中?这样会更有效率,不是吗?
    • 嗯,这个问题的答案是 jvm 并不是为支持 1 位操作而构建的,因此“bool”只是一个使用另一个名称的字节。使用 1 位节省的内存量是如此之小,不值得增加计算复杂性。
    • 如果他们将布尔值存储到一个位中,可能会涉及更多的开销,因为今天的 CPU 并不是为了获取一个位的内存而设计的。
    • 这个回答不太对。我不知道 JVM 内部是如何工作的,但至少在 x86 内存地址引用单个字节上,请澄清这一点。
    • 看我的回答。它可能会解释一些事情。
    猜你喜欢
    • 2011-04-17
    • 1970-01-01
    • 1970-01-01
    • 2018-03-21
    • 1970-01-01
    • 2023-04-09
    • 2018-08-02
    • 2020-10-21
    • 2014-05-25
    相关资源
    最近更新 更多