【问题标题】:How much memory allocates to element in Object[]Object[] 中的元素分配了多少内存
【发布时间】:2014-05-20 20:48:08
【问题描述】:

考虑以下情况

int[] anArray = new int[10]; 

为堆上每个32位的10个元素分配内存。对吗?

如果元素类型是Object,那么元素的大小是多少。 ??

喜欢

Object[] objArray = new Object[10];

现在在堆上分配了多少内存?我刚刚通过ssing ArrayList的源代码得到了疑问。

  private transient Object[] elementData;

刚刚在我的机器上试过这条线

List<String> s = new ArrayList<String>(Integer.MAX_VALUE);

结果

Exception in thread "main" java.lang.OutOfMemoryError: Requested array size exceeds VM limit
    at java.util.ArrayList.<init>(Unknown Source)
    at com.nextenders.server.guice.actions.servlets.Test.main(Test.java:13)

所以我想知道分配了多少内存。

【问题讨论】:

  • 请允许我从@Duncan 链接问题中提取(并稍微调整)相关的 sn-ps:New Object[10] creates space for 10 Object references only. It does not create 10 Object objects (or even free space for 10 Object objects)Each reference will be an address: 32 bit on 32 bit CPU, 64 at 64
  • 是的,请参阅or even free space for 10 Integer objects 行。那么为什么OutOfMemoryError 只是为了初始化而发生呢??
  • 因为ArrayList&lt;String&gt;(Integer.MAX_VALUE); 请求了 2^(31-1) 个地址。
  • 奇怪的情况我很好奇解决方案

标签: java arrays memory-management


【解决方案1】:

如果元素类型是Object,那么元素的大小是多少。 ??

Object[] 数组元素的大小是引用的大小。

  • 在 32 位 JVM 上,引用是 32 位(4 个字节)

  • 在 64 位 JVM 上,引用为 64 位(8 字节),如果启用了“压缩 oop”优化且堆大小小于 32Gb,则为 32 位。

因此,您的数组分配将分配一个堆对象,其中包含大约 4 x 10 或 8 x 10 字节......加上大约 12 字节的对象头开销。

刚刚在我的机器上试过这条线

List<String> s = new ArrayList<String>(Integer.MAX_VALUE);

在幕后,您正在尝试分配尝试分配包含 233 和 234 字节之间的数组。使用 32 位 JVM,保证不会工作。使用 64 位 JVM,您需要至少 8Gb(压缩 oop)或 16Gb 的堆才能工作。

【讨论】:

  • 来自 Oracle 的报价:indicates that the application [...] attempted to allocate an array that is larger than the heap size
  • @MarkoTopolnik - 我明白了。
  • @StephenC 12 字节的对象头开销,由于内存对齐,16 字节。
  • @Eugene - 这取决于 JVM 实现。这就是为什么我说 大约 12 个字节。
  • @StephenC 确实如此。在 JVM 7 update 51 上,它是 16 字节,刚刚测试出来。实际上,由于这种内存对齐,我们可以使用压缩 oop,因为最后 3 位始终是空闲的。
【解决方案2】:
  1. 10 x 4 字节 = 40 字节
  2. 对象存储的最大大小是 256 MB 的可压缩空间, 非易失性,RAM 存储。对象存储的大小可以是 更改为自定义可用的持久存储量 应用程序及其相关数据。默认对象 = 4 字节 x32bit 和 x64bit 中的 8bytes
  3. 这取决于对象持有的物品。既然你是 不在对象中分配任何项目,因此堆将由 默认对象 = 4 字节 x 10 = 40 字节。

【讨论】:

    【解决方案3】:

    它将创建一个包含 10 个 32 位对象引用的数组(存储对象的内存地址),因为 java 中的所有对象都只是指向存储对象的内存的指针。或者,如果您使用的是 64 位机器,地址将是 64 位

    【讨论】:

      猜你喜欢
      • 2012-08-28
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-01-03
      • 2017-05-18
      • 1970-01-01
      • 1970-01-01
      • 2017-01-30
      相关资源
      最近更新 更多