Java对象数组内存要求

时间:2013-03-21 14:42:34

标签: java memory-management

假设我的班级中有一个Integer数组:

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

}

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

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

1 个答案:

答案 0 :(得分:2)

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

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

通过这些和许多其他约束,始终存储引用是唯一可行的实现策略(通常)。在非常特定的情况下,JIT编译器可以避免完全分配对象并直接存储它(例如在堆栈上),但这是一个模糊的实现细节,并且不能广泛应用。我只是提到这一点是为了完整性,因为它是对as-if规则的精彩说明。