【问题标题】:Java GC: Are rows of generic arrays independent objects?Java GC:通用数组的行是独立对象吗?
【发布时间】:2013-03-05 05:29:11
【问题描述】:

当我执行以下操作时:

public double[] someFn()
{
    double[][] b = new double[5][5];
    return b[2];
}

缓冲区 b 的其余部分是否已准备好用于垃圾箱,或者第二行仍在使用的某个地方是否会阻止整个数组 b 被收集?

当我谈论通用数组时,我无法测试最终确定...

【问题讨论】:

  • 虽然它们被分配为可以独立存在的独立对象,但它们通常在内存中连续分配并在 GC 后一起保留在内存中(假设它们都通过一个引用保留)

标签: java arrays multidimensional-array garbage-collection


【解决方案1】:

是的,b 的每个元素只是double[] 的引用。每个元素都可以是对独立对象的引用 - 或者多个元素可以引用同一个数组,或者具有空值。

从元素到包含它的数组没有“反向链接”。

基本上,您应该将“多维”数组视为普通数组,其中元素类型 恰好 是另一个数组。比如:

String foo() {
    String[] array = getStrings();
    return array[0];
}

该方法返回的字符串引用对数组一无所知,它所引用的字符串对象也不知道。数组数组的方式完全相同。

【讨论】:

  • 您在哪里可以找到此类信息? Java 如何在内部处理内存分配情况,例如 OP 所描述的情况?有没有我可以阅读的规范或类似的东西来理解?还是只是阅读源码?
  • @KevinBowersox:Java 语言规范是一个好的开始:docs.oracle.com/javase/specs/jls/se7/html/index.html
【解决方案2】:

在 someFn() 返回后, b 的其他元素将准备好被 gc-ed,因为您无法获得它们的任何引用。 我写了一个小程序来证明:

public class GCDemo {

static class OneMB {
    byte[] data = new byte[1024 * 1024];
    String name;

    public OneMB(String name) {
        this.name = name;
    }
    protected void finalize() throws Throwable {
        System.out.println(name + " gc-ed");
    }
}

public static OneMB[] someFn() {
    OneMB[][] b = new OneMB[3][3];
    for (int i = 0; i < b.length; i++) {
        for (int j = 0; j < b[i].length; j++) {
            b[i][j] = new OneMB(i + "-" + j);
        }
    }
    return b[2];
}

public static void main(String[] args) throws InterruptedException {
    OneMB[] b2 = someFn();
    System.gc();
    System.gc();
    Thread.sleep(6000);
    System.out.println("after b2 is released");
    b2 = null;
    System.gc();
    Thread.sleep(2000);
}

}

输出是

0-2 gc-ed

1-2 gc-ed

1-1 gc-ed

0-1 gc-ed

0-0 gc-ed

1-0 gc-ed

b2 发布后

2-2 gc-ed

2-1 gc-ed

2-0 gc-ed

【讨论】:

    猜你喜欢
    • 2012-02-05
    • 1970-01-01
    • 2011-06-15
    • 1970-01-01
    • 1970-01-01
    • 2014-01-22
    • 1970-01-01
    • 2011-09-30
    • 1970-01-01
    相关资源
    最近更新 更多