关于我的 OCA 考试的垃圾收集问题
Question about Garbage Collection for my OCA Exam
class CardBoard {
Short story = 200;
CardBoard go(CardBoard cb){
cb = null;
return cb;
}
public static void main(String[] args){
CardBoard c1 = new CardBoard();
CardBoard c2 = new CardBoard();
CardBoard c3 = c1.go(c2);
c1 = null;
// When this line is reached, what is eligible for the GC.
}
}
有人可以解释一下这里发生了什么吗?我了解 c1
和 Short
有资格使用垃圾收集器。但是 c2
会发生什么,为什么 c3
也不能用呢?我可能会在这里监督一些事情,但我很高兴能够帮助我解决这个话题的每一个输入。我的 OCA 考试是下周,我仍然对这些东西感到困扰。
编辑:符合 GC 条件的评论。
考虑到 Java 是按值传递,我们知道 Java 不是传递对象,而是传递对象的引用。
因此,当您执行 CardBoard c3 = c1.go(c2);
时,方法 go(Cardboard cb)
只是将 c2 的引用值复制到 cb,因此 c2 不会受到 cb = null;
的伤害。因此,c2 不符合 GC 的条件。
c3 永远不会被构造为一个对象,它只是一个初始化为 null 的 CardBoard 类型的变量。因此,它不能被垃圾收集,因为它甚至没有在堆上创建。
也许可视化所涉及的对象会有所帮助。在 main 中的第一条语句之后,我们有:
+-----------+ +-------+
| CardBoard | ---> | Short |
c1 ----> |-----------| / |-------|
| story | / | 200 |
+-----------+ +-------+
在 main 中的第二个语句之后,我们有:
+-----------+ +-------+
| CardBoard | ---> | Short |
c1 ----> |-----------| / |-------|
| story | / | 200 |
+-----------+ +-------+
+-----------+ +-------+
| CardBoard | ---> | Short |
c2 ----> |-----------| / |-------|
| story | / | 200 |
+-----------+ +-------+
(理论上也有可能是两个CardBoard共享了Short
对象,Short.valueOf
的Javadoc说:
This method will always cache values in the range -128 to 127, inclusive, and may cache other values outside of this range.
但是,JDK 实现仅在 -128 到 127 范围内缓存,因此我们将假设继续前进)
进入 go() 方法后,我们有:
+-----------+ +-------+
| CardBoard | ---> | Short |
c1 ----> |-----------| / |-------|
| story | / | 200 |
+-----------+ +-------+
+-----------+ +-------+
| CardBoard | ---> | Short |
c2 ----> |-----------| / |-------|
--> | story | / | 200 |
/ +-----------+ +-------+
/
/
cb
在离开 go() 之前,我们有:
+-----------+ +-------+
| CardBoard | ---> | Short |
c1 ----> |-----------| / |-------|
| story | / | 200 |
+-----------+ +-------+
+-----------+ +-------+
| CardBoard | ---> | Short |
c2 ----> |-----------| / |-------|
| story | / | 200 |
+-----------+ +-------+
cb --x
在 main 中的第 3 个语句之后,我们有:
+-----------+ +-------+
| CardBoard | ---> | Short |
c1 ----> |-----------| / |-------|
| story | / | 200 |
+-----------+ +-------+
+-----------+ +-------+
| CardBoard | ---> | Short |
c2 ----> |-----------| / |-------|
| story | / | 200 |
+-----------+ +-------+
c3 --x
在离开 main() 之前,我们有:
+-----------+ +-------+
| CardBoard | ---> | Short |
c1 -x |-----------| / |-------|
| story | / | 200 |
+-----------+ +-------+
+-----------+ +-------+
| CardBoard | ---> | Short |
c2 ----> |-----------| / |-------|
| story | / | 200 |
+-----------+ +-------+
c3 -x
正如我们所见,在分配的 4 个对象中,2 个保持可达,2 个符合回收条件。
class CardBoard {
Short story = 200;
CardBoard go(CardBoard cb){
cb = null;
return cb;
}
public static void main(String[] args){
CardBoard c1 = new CardBoard();
CardBoard c2 = new CardBoard();
CardBoard c3 = c1.go(c2);
c1 = null;
// When this line is reached, what is eligible for the GC.
}
}
有人可以解释一下这里发生了什么吗?我了解 c1
和 Short
有资格使用垃圾收集器。但是 c2
会发生什么,为什么 c3
也不能用呢?我可能会在这里监督一些事情,但我很高兴能够帮助我解决这个话题的每一个输入。我的 OCA 考试是下周,我仍然对这些东西感到困扰。
编辑:符合 GC 条件的评论。
考虑到 Java 是按值传递,我们知道 Java 不是传递对象,而是传递对象的引用。
因此,当您执行 CardBoard c3 = c1.go(c2);
时,方法 go(Cardboard cb)
只是将 c2 的引用值复制到 cb,因此 c2 不会受到 cb = null;
的伤害。因此,c2 不符合 GC 的条件。
c3 永远不会被构造为一个对象,它只是一个初始化为 null 的 CardBoard 类型的变量。因此,它不能被垃圾收集,因为它甚至没有在堆上创建。
也许可视化所涉及的对象会有所帮助。在 main 中的第一条语句之后,我们有:
+-----------+ +-------+
| CardBoard | ---> | Short |
c1 ----> |-----------| / |-------|
| story | / | 200 |
+-----------+ +-------+
在 main 中的第二个语句之后,我们有:
+-----------+ +-------+
| CardBoard | ---> | Short |
c1 ----> |-----------| / |-------|
| story | / | 200 |
+-----------+ +-------+
+-----------+ +-------+
| CardBoard | ---> | Short |
c2 ----> |-----------| / |-------|
| story | / | 200 |
+-----------+ +-------+
(理论上也有可能是两个CardBoard共享了Short
对象,Short.valueOf
的Javadoc说:
This method will always cache values in the range -128 to 127, inclusive, and may cache other values outside of this range.
但是,JDK 实现仅在 -128 到 127 范围内缓存,因此我们将假设继续前进)
进入 go() 方法后,我们有:
+-----------+ +-------+
| CardBoard | ---> | Short |
c1 ----> |-----------| / |-------|
| story | / | 200 |
+-----------+ +-------+
+-----------+ +-------+
| CardBoard | ---> | Short |
c2 ----> |-----------| / |-------|
--> | story | / | 200 |
/ +-----------+ +-------+
/
/
cb
在离开 go() 之前,我们有:
+-----------+ +-------+
| CardBoard | ---> | Short |
c1 ----> |-----------| / |-------|
| story | / | 200 |
+-----------+ +-------+
+-----------+ +-------+
| CardBoard | ---> | Short |
c2 ----> |-----------| / |-------|
| story | / | 200 |
+-----------+ +-------+
cb --x
在 main 中的第 3 个语句之后,我们有:
+-----------+ +-------+
| CardBoard | ---> | Short |
c1 ----> |-----------| / |-------|
| story | / | 200 |
+-----------+ +-------+
+-----------+ +-------+
| CardBoard | ---> | Short |
c2 ----> |-----------| / |-------|
| story | / | 200 |
+-----------+ +-------+
c3 --x
在离开 main() 之前,我们有:
+-----------+ +-------+
| CardBoard | ---> | Short |
c1 -x |-----------| / |-------|
| story | / | 200 |
+-----------+ +-------+
+-----------+ +-------+
| CardBoard | ---> | Short |
c2 ----> |-----------| / |-------|
| story | / | 200 |
+-----------+ +-------+
c3 -x
正如我们所见,在分配的 4 个对象中,2 个保持可达,2 个符合回收条件。