【问题标题】:java loitering and garbage collectionjava游荡和垃圾收集
【发布时间】:2013-08-09 05:09:34
【问题描述】:

我有这段代码用于 Stack 的 pop 方法,我正在尝试弄清楚它如何避免徘徊,同时仍然返回我们的索引当前指向的元素:

public String pop()
{ // Remove item from top of stack.
String item = a[--N];
a[N] = null; // Avoid loitering (see text).
if (N > 0 && N == a.length/4) resize(a.length/2);
return item;
}

据我所知,我们将 String 对象的引用项指向数组 a 的索引元素(我们从最后一个元素开始,使用它的当前大小 N-1 因此递减)。那么,如果我们要返回引用,为什么要在这样做之前将引用指向的索引元素设置为 null 呢?这不会使项目指向任何内容并且不返回任何内容吗?

【问题讨论】:

  • Java 中的引用总是复制,因此通过修改数组中的内容,您不会改变从中得到的内容。

标签: java memory garbage-collection stack


【解决方案1】:

复制数组中的引用。它不引用数组成员。

 String item = a[--N];

现在你有两个对同一个对象的引用,一个在局部变量中,一个在数组中。这将删除数组中的副本:

 a[N] = null; // Avoid loitering (see text).

如果它没有从数组中删除,那么不必要的引用将继续存在,从而阻止垃圾回收。

【讨论】:

    【解决方案2】:

    只要对象是可访问的,它就不能被垃圾回收。如果您只是用--N 更改索引但不使a[N] 无效,您将保留对该对象的引用,即使客户端代码不再引用该对象,也会阻止其垃圾回收。

    这是您需要在 Java 中使变量无效的唯一情况之一。

    您似乎也误解了引用是什么。 a[N] 包含一个指向内存中对象的值。当您写入String item = a[N] 时,您将该值复制到变量item。两个变量(itema[N])现在都指向同一个对象。然后,当您编写 a[N] = null 时,您会从数组中删除该引用,但 item 仍然包含指向原始对象的值。

    【讨论】:

    • 啊对 a 也是一个引用,但是指向数组对象。我明白了,谢谢。
    • 所以您将数组的引用(我们对象的内存位置)复制到我们的 String 对象的项目引用的引用。所以现在 item 指向数组对象。将我们的引用 a 设置为 null 是取消引用它,因为我们不再需要它。问题:数组是否有多个引用,例如 C++ 如何处理内存(每个索引都指向内存中的某个空间)?所以本质上我们只是取消引用它的某个部分(所以垃圾收集器可以收集)?
    • @user2644819 项目不指向数组对象。它指向与a[N] 指向的对象相同的对象。这篇文章可能会让事情更清楚:stackoverflow.com/questions/40480/is-java-pass-by-reference
    • 字符串[] a; a = 新字符串[N];那么引用是否指向 String 对象?所以参考项目也应该指向那个,不是吗?
    • in String[] a = new String[N], a 包含一个指向恰好是数组的对象的引用。每个数组项,例如a[0],都包含一个指向字符串的引用。
    猜你喜欢
    • 2010-12-13
    • 2011-01-06
    • 1970-01-01
    • 1970-01-01
    • 2011-11-07
    • 2012-07-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多