我正在审核Java
垃圾收集流程以及GC
适用的不同方案。
以下是我感到困惑的情景:
List<X> listX = new ArrayList<X>();
for(int a = 0;a<100;a++){
listX.add(new X(a));
}
for (X xObject : listX) {
xObject.printValue();
}
在第一个循环中,我在每个循环中添加新对象,在最新循环中我只是打印值,因此,我在GC
列表中添加的那些对象是什么?
这句话是什么意思?
&#34;当一个实例有资格进行垃圾收集时,这是一个更好的例子。实例的所有属性都可以存储在寄存器中,然后访问寄存器以读取值。将来不会将值写回实例。虽然这些值可以在将来使用,但仍然可以将此实例标记为有资格进行垃圾收集&#34;
答案 0 :(得分:9)
不,它们不是,因为它们被ArrayList引用的数组引用,ArrayList的引用位于当前线程的堆栈中:
thread stack --> ArrayList --> array --> x1, x2, x3, etc.
答案 1 :(得分:3)
您添加到列表中的对象的生命周期与robots.txt
本身的生命周期有关,因为从我从代码中看到的内容,list
是唯一保持对{{{{ 1}}对象。
因此,当listX
不再被引用时,将收集X
个对象。
检查@JBNizet以查看它们实际引用或连接的方式(+1)。总是这样想,我的对象是如何连接的,如果他们仍然一直引用GC Roots,并且记住X
很聪明,那就不会reference counting:)
答案 2 :(得分:1)
如果您考虑以下代码,请稍微更改一下。
List<X> listX = new ArrayList<X>();
for(int a = 0;a<100;a++){
X tmpX = new X(a);
X unusedX = new X(a);
listX.add(tmpX);
}
调用new关键字时,会在堆上创建一个新对象。这意味着在此示例中,它将创建tmpX
和unusedX
。您正在将tmpX
添加到数组中,因此意味着它在ListX
中有引用。当它是垃圾收集时间时,垃圾收集器将检查那些只存在于由{}括号定义的for范围的当前迭代中的对象。将收集unusedX
,但由于tmpX
将在列表中包含引用,因此它将保留在堆中。
答案 3 :(得分:0)
垃圾收集仅释放由任何根不再可以强烈访问的对象所占用的内存,例如在循环依赖的情况下。每个新X
对象的引用都保存在List
中,因此不会收集垃圾。
答案 4 :(得分:0)
不,如果这段代码可以访问,如果不可以,那么它将难以辨认。垃圾收集器将查找不再使用的对象,删除它们并释放内存。