【问题标题】:Does Java garbage collector collect even if a reference out of scope is further referenced?即使进一步引用超出范围的引用,Java 垃圾收集器也会收集吗?
【发布时间】:2019-10-03 15:39:06
【问题描述】:

请考虑以下代码:


import java.util.*;
import java.lang.*;
import java.io.*;

/* Name of the class has to be "Main" only if the class is public. */


class Ideone
{
    public static List<String> arraylist=new ArrayList<String>();

    //add hello n times to the list
    public static void add_to_list(int n)
    {
        if(n==0)
        {
            return;
        }
        else
        {
            String b=new String("hello");
            arraylist.add(b);
            add_to_list(n-1);
        }
    }

    public static void main(String args[]) throws IOException
    {
        add_to_list(5);
        for(String s:arraylist)
        {
            System.out.println(s);
        }
    }
}

我已尝试多次运行此程序,得到的输出与以下内容相同:

hello
hello
hello
hello
hello

我的假设:

  1. 一旦方法 add_to_list 被执行,字符串 b 就会超出范围
  2. 我在其范围之外引用了 arraylist 引用索引
  3. Arraylist 包含方法中创建的字符串的引用。

因此我的问题是:

  1. 在我打印值之前,Java 收集器是否有可能清理引用?
  2. 我是不是很幸运,在读取这些值之前 Java 收集器没有运行?

【问题讨论】:

  • 垃圾收集器只会收集没有strong引用的对象。
  • @Slaw 你能解释一下什么是强参考吗?
  • variable b 超出范围,但该对象仍然存在并且不符合 GC 条件,因为该列表包含对它的引用。如果该项目从列表中删除,它将有资格获得 GC。
  • @SouravKanta 正确。垃圾收集器是专门设计的,因此您永远看不到它在工作。
  • @SouravKanta 不同之处在于,在 Java 中,除了原语和引用之外,堆栈上实际上不存在任何东西。所有对象都在堆栈外分配。为了补偿将所有内容都堆积到堆上,有一个内存用于池中新创建的对象 - “young gen” - 从中​​积极地剔除对象。

标签: java


【解决方案1】:

您的变量arraylist 是静态的,因此不会超出范围。因此,它会一直保持对其元素的引用,直到程序结束。

它们不能被垃圾收集,所以你不是“幸运的”。

【讨论】:

    【解决方案2】:

    当您使用 new() 运算符创建字符串时,它总是在堆内存中创建一个新对象。在上面的代码中,每次调用 add_to_list() 时,它都会在堆内存中创建一个新的字符串对象,并且它的引用存储在局部变量“b”中,该变量位于 add_to_list() 的堆栈内存中。每次调用此方法时,都会分配新的堆栈内存,并在完成该特定调用的执行后,清除其分配的堆栈内存。

    但您也将此字符串对象引用(即“b”)添加到静态 ArrayList。静态变量存储为与类关联的 Class 对象的一部分,并驻留在堆内存中的 PermGen 中,只要类在内存中,它就会一直存在。

    垃圾收集总是通过清除没有任何引用的任何对象来释放内存。这些是不再使用的对象。但是在您上面的代码中,所有字符串引用都存储在静态列表中,因此只有在类终止时才会对它们进行垃圾收集。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-10-22
      • 1970-01-01
      • 1970-01-01
      • 2012-04-18
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多