Java 对象数组内存要求

标签 java memory-management

假设我的类中有一个整数数组:

public class Foo {
   private Integer[] arr = new Integer[20];
   .....

}

在 64 位架构上,此空间要求为 ~ (20*8+24) + 24*20 {引用所需的空间 + 一些数组开销 + 对象所需的空间}。

为什么 java 存储对所有 20 个 Integer 对象的引用?不知道第一个内存位置和数组中的项数是否足够? (假设我也在某处读到数组中的对象无论如何都是连续放置的)。我想知道这种实现的原因。对不起,如果这是一个笨拙的问题。

最佳答案

与所有其他 一样,Integer 是引用类型。这意味着它只能通过引用间接访问。您不能在字段、局部变量、集合中的插槽等中存储引用类型的实例——您始终必须存储引用并单独分配对象本身。这有多种原因:

  • 您需要能够表示 null
  • 您需要能够用 子类型 的另一个实例替换它(假设子类型是可能的,即该类不是final)。例如,Object[] 实际上可以存储任意数量的不同类的实例,这些类的大小差异很大。
  • 您需要保留共享,例如a[0] = a[1] = someObject; 所有三个 之后必须引用相同 对象。如果对象是可变的,这一点就更为重要(甚至至关重要),但即使是不可变对象(immutable对象),也可以通过引用相等性检查 (==) 观察到差异。
  • 您需要原子的引用分配(参见 Java 内存模型),因此复制整个实例比看起来更昂贵。

由于这些和许多其他限制,始终存储引用是唯一可行的实现策略(通常)。在非常特殊的情况下,JIT 编译器可能会避免完全分配一个对象并直接存储它(例如在堆栈上),但这是一个模糊的实现细节,并不广泛适用。我只是为了完整性而提及这一点,因为它是对假设规则的精彩说明。

关于Java 对象数组内存要求,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/15550611/

相关文章:

java - 无法在 IntelliJ Idea 中启动 spring-boot 应用程序

java - 如何将在 iOS 或 Android 上运行的 JavaFX 应用程序连接到 native 库?

c - Free() 返回的 char 指针不会将其从内存中删除?

debugging - 什么是私有(private)字节、虚拟字节、工作集?

java - 自定义类加载器问题

java - 由于 web.xml,内容未显示在 profile.jsp 上?

java - 将 double 格式格式化为小数点后两位 - 编译错误

c - .Call mdsplib - METAR - 缓冲区溢出 - 这个 valgrind 输出是什么意思?

java - Java 中字符串是如何创建和存储的?

json - 使用 Echo 或 Gin 框架的大型数组的内存消耗