为什么堆栈帧中局部变量数组的每个槽都是 4 个字节,而不是 JVM 中的 1 个字节?

Why each slot of the local variable array in a stack frame is of 4 bytes, and not 1 byte in the JVM?

局部变量数组的每个槽为4字节。因此,要存储一个字符、短或字节变量,使用一个槽。意味着所有较小的数据类型都在内部转换为 int 数据类型。

我的疑问是:

1).如果较小的数据类型在内部是 4 字节,它不会使较小的数据类型变得无用吗?如果是,为什么不从语言中删除此类数据类型? 2).如果每个插槽都是 1 字节,那么就不会浪费内存。为什么不是每个槽都是 1 字节的?

由于数组,我们无法从语言中删除 bytesbyte 的数组比 int 的数组小四倍。

并且没有理由将变量槽设置为 1 字节,因为它不会节省太多内存(堆栈通常比堆小得多)并且如果填充所有内容,内存工作得更快。

Is it not making smaller data types useless, if internally they are of 4-bytes?,

寄存器始终为 32 位或 64 位,具体取决于体系结构。当您在内存中存储大量值时,使用 1 个字节、2 个字节或 4 个字节加起来也不会减少。

If each slot is of 1-byte then there will be no wastage of memory. Why not each slot is of 1-byte?

一个字节只能存储256个值,不能存储更大的范围。我想你的意思是;为什么不是所有内容都是 1 字节的倍数?这无关紧要,因为内存使用是虚拟的。实际内存使用可以优化。

局部变量存储在4个字节中(bytecharshortintbooleanfloat、引用到对象)或 8 个字节(longdouble)。

但是变量并不是只在函数局部需要的。 序列化可以使用最小的字节数。

速度性能和 space 占用率之间存在混合。

访问 4 字节变量更快,因为现代 CPU 使用 32 位或 64 位寄存器,因此任何从 4 块中提取少量字节的操作都是浪费时间 cpu.

1). Is it not making smaller data types useless, if internally they are of 4-bytes?

当涉及局部变量或算术时,是的,使用较小的数据类型可能没有用,甚至会因为需要值集转换而浪费性能。

然而,除了局部变量之外,还有一个 ,对于字段和数组,它可以产生(特定于实现的)差异。

If yes, Why not remove such data-types from the language?

首先,如上所述,是堆。其次,有 I/O。您正在以字节或字符或现在的代码点的形式与外界交换数据。因此,除了存储大小之外,这些数据类型还带有语义。调用 StringBuilder.append(char)StringBuilder.append(byte) 会有很大的不同,尽管在这两种情况下,实际上传递的是 int 值。

2). If each slot is of 1-byte then there will be no wastage of memory. Why not each slot is of 1-byte?

如果每个槽都是一个字节,就不可能在其中存储任何其他内容。您将堆栈帧槽(用于局部变量和操作数堆栈)与实际存储混淆了。插槽旨在保存任意数据类型的值,并且可以以依赖于实现的方式映射到实际存储或 CPU 寄存器。 longdouble 占用两个插槽的事实是历史妥协,源于 Java 是上个世纪九十年代初设计的事实。

如果今天设计,您可以打赌,一个插槽将被定义为能够容纳 所有 数据类型,包括 longdouble .这里的重点是架构的简化。如果对局部变量或特定底层架构的操作数使用较小的数据类型有潜在好处,则由 JVM 实现检测到这一点并生成适当的本机代码。如前所述,在大多数情况下,由于局部变量和操作数堆栈条目被映射到 CPU 寄存器,因此没有这样的好处。