【问题标题】:Does a byte primitive become a byte in memory when indirectly inside an array?当间接在数组中时,字节原语是否会成为内存中的字节?
【发布时间】:2016-02-29 02:42:32
【问题描述】:

听说一个字节本身占用内存4个字节,字节数组内一个字节占用1个字节,那么数组内对象内的字节成员变量呢?

class SomeObject {
    byte iBite;
}

public static void main(String[] args) {
    SomeObject[] objs = ...
}

每个 SomeObject 的 iBite 变量在内存中是否只有 1 个字节?

【问题讨论】:

  • 不,它将是“一个字节本身”并占用 4 个字节,如果没有其他原因,对象大小几乎肯定会被四舍五入。
  • 对象至少有 8 个字节的开销,并且在 8 个字节的边界上对齐,你的对象是 8+1=9 个字节(至少),所以会占用 16 个字节的内存。该数组存储对对象的引用,这些对象本身至少有 4 个字节长,因此 SomeObject[100] 使用 100*(16+4)=2000 字节(至少)的内存(假设分配给完整数组的不同对象),而 @ 987654324@ 使用 100 字节的内存。两者都是对数组本身 12+ 字节开销的补充。
  • 对象内的一个字节将占用 1-4 个字节,具体取决于月相。
  • @Andreas 100 个“对象”的数组占用单个引用(即指针)大小的 100 倍。 (对象本身当然占用更多,但它们是分开分配的。)
  • @HotLicks 我知道。这就是为什么我说 100 * 4 用于引用,加上 100 * 16 用于对象,即 100 * (16 + 4) = 2000 字节。

标签: java arrays memory bytearray


【解决方案1】:

一个字节作为一个局部变量被实现为int,所以它需要4个字节。

一个字节作为一个类的 字段(就像在你的例子中一样)占用 1 个字节的内存,但是内存中的类被四舍五入到例如 8 个字节的倍数。热点 JVM。也就是说,如果您有一个包含多个 byte 字段(或 char 或 short 字段)的类,它们将更有效地利用内存。

数组是相似的:每个byte 将占用 1 个字节,但整个数组将向上取整为 8 个字节的倍数,例如HotSpot JVM。

您可以使用http://openjdk.java.net/projects/code-tools/jol/ 手动进行实验。如果你使用它,例如,在

public static class A {
    boolean f;
    byte g;
    int h;
}

我明白了

Running 64-bit HotSpot VM.
Using compressed oop with 3-bit shift.
Using compressed klass with 3-bit shift.
Objects are 8 bytes aligned.
Field sizes by type: 4, 1, 1, 2, 2, 4, 4, 8, 8 [bytes]
Array element sizes: 4, 1, 1, 2, 2, 4, 4, 8, 8 [bytes]

org.openjdk.jol.samples.JOLSample_01_Basic.A object internals:
 OFFSET  SIZE    TYPE DESCRIPTION                    VALUE
      0    12         (object header)                N/A
     12     4     int A.h                            N/A
     16     1 boolean A.f                            N/A
     17     1    byte A.g                            N/A
     18     6         (loss due to the next object alignment)
Instance size: 24 bytes (estimated, the sample instance is not available)
Space losses: 0 bytes internal + 6 bytes external = 6 bytes total

这很清楚地表明boolean 和byte 将一个字节作为对象字段。

如您所料,char 和 short 是 2 个字节,int 和 float 是 4 个字节,long 和 double 是 8 个字节。

https://stackoverflow.com/a/14782255/869736 解释了有关 Dalvik 的一些细节,包括目前像 byte 这样的小字段实际上是用 4 个字节实现的。请记住,这些细节将取决于 VM。

【讨论】:

  • 一个字节作为类字段需要4个字节。
  • @AlexWien 不在普通的 HotSpot 虚拟机上。
  • 热点事件,你的信息来自哪里?
  • @AlexWien 将填充单个字段,因此虽然一个字节字段可能需要 4 个字节,但 4 个字节字段也只需要 4 个字节。 :)
  • @AlexWien 您可以使用openjdk.java.net/projects/code-tools/jol 手动进行实验,因为它来自实际编写 Java 的 OpenJDK 人员。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-04-26
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多