【问题标题】:What is the memoy size of a Java object array after it has been created?Java对象数组创建后的内存大小是多少?
【发布时间】:2012-11-01 14:08:16
【问题描述】:

这可能甚至不需要问,但我想确保我是对的。当你像这样在 Java 中创建任何对象的数组时:

Object[] objArr = new Object[10];

变量objArr位于栈内存中,它指向堆中数组对象所在的位置。堆中该数组的大小等于 12 字节对象头 + 4(或 8,取决于参考大小)字节 * 数组中的条目数。这准确吗?

那么,我的问题如下。由于上面的数组是空的,那么在执行那行代码后,它是否立即占用了堆中 12 + 4*10 = 52 字节的内存?还是 JVM 会等到您开始将东西放入数组中后再实例化它?数组中的空引用占用空间吗?

【问题讨论】:

  • 只是给您一些术语,您实际上是在询问 Java 数组是否为“sparse arrays
  • 无论是指向null还是什么,reference就是reference,在这种情况下它恰好是Object类型。但这是个好问题,+1。
  • 哦,谢谢大家。我不确定这些知识是如何从我的裂缝中溜走的!

标签: java arrays memory


【解决方案1】:

空引用确实“占用空间”——数组的内存被预先分配在一个块中,然后归零(使所有内容都为空引用)。作为一个练习,尝试分配一个巨大的数组,它会占用比 JVM 的内存限制更多的空间。程序应立即因内存不足错误而终止。

【讨论】:

  • 这是个好主意!一旦我进入了数十亿个元素,我就用尽了堆空间。
【解决方案2】:

我认为这对你有帮助

public static void main(String[] args) {
        Runtime r = Runtime.getRuntime();
        System.gc();
        System.out.println("Before " + r.freeMemory());
        Object[] objArr = new Object[10];
        System.out.println("After " + r.freeMemory());
        objArr[0] = new Integer(3);
        System.gc();
        System.out.println("After Integer Assigned " + r.freeMemory());
    }

输出

Before 15996360
After 15996360
After Integer Assigned 16087144

【讨论】:

  • 这个输出相当具有误导性;数组内存应该在new Object[10] 表达式中分配。您可能会看到优化器对语句重新排序的效果; AFAICT 这里没有记忆障碍。 (换句话说,优化器可能正在交换 Object[] objArr = new Object[10];System.out.println("After " + r.freeMemory()); 语句。)
  • 你怎么说这是误导?这可能会解决您的问题
  • 因为输出导致您相信数组内存在分配之前没有分配。但是,可能发生的情况是优化器正在对您重新排序语句,并且只是将数组分配移动到第二次println() 调用之后。
  • 我不知道你可以在 Java 中看到这样的空闲内存。似乎很难解释所使用的预测内存量的差异,这一定是由于@cdhowie 所说的优化器。有用,但不一定能准确解释内存的使用方式。
猜你喜欢
  • 2011-01-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-08-19
  • 2013-09-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多