java java中的垃圾收集示例?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/11761156/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-31 06:16:29  来源:igfitidea点击:

Garbage collection example in java?

javagarbage-collection

提问by MKod

class Beta { }

class Alpha {
static Beta b1  ;
Beta b2;
}

public class Tester {

public static void main(String[] args) {

    Beta b1 = new Beta();
    Beta b2 = new Beta();
    Alpha a1 = new Alpha();
    Alpha a2 = new Alpha();

    a1.b1 = b1 ;
    a1.b2 = b1 ;
    a2.b2 = b2 ;

    a1 = null ;
    b1 = null;
    b2 = null;

    System.out.println(" Line 1    " + " a1   "  + a1.b1);
    System.out.println(" Line 2    " + " a1   "  + a1.b2);
    System.out.println(" Line 3    " + " a2   " + a2.b2);
    System.out.println(" Line 4    " + " a1   " + a2.b1);
    System.out.println(" Line 5    " + " b1   " + b1);
    System.out.println(" Line 6    " + " b1   " + b2);

  }

 }  

I am not sure why only a1 object is available for garbage collection in the above program. I am expecting a1 , b1 and b2 to be collected by garbage collector.

我不确定为什么在上面的程序中只有 a1 对象可用于垃圾收集。我期待 a1 、 b1 和 b2 被垃圾收集器收集。

As you can see a1 , b1 and b2 were made NULL hence this is making objects to be available for garbage collection. If object is NULL or unreachable by any thread or reference variable it should be collected by garbage collector.

如您所见, a1 、 b1 和 b2 被设为 NULL,因此这使得对象可用于垃圾收集。如果对象为 NULL 或无法被任何线程或引用变量访问,则应由垃圾收集器收集。

Can someone help me understand the subtleness of the above program with good example and in more precise way ? Your help is appreciated.

有人可以用很好的例子和更精确的方式帮助我理解上述程序的微妙之处吗?感谢您的帮助。

回答by kosa

Because there is still reference exists to objects pointed by b1 & b2 refrences due to below lines.

因为仍然存在对 b1 和 b2 引用指向的对象的引用,因为下面的行。

a1.b1 = b1 ;
a1.b2 = b1 ;
a2.b2 = b2 ;

Assume like this:

假设如下:

  b1--->BetaObj1
    b2---BetaObj2
    a1---> AlphaObj1
    a2---> AlphaObj2

a1.b1 points to b1 that means, there is reference to BetaObj1 a1.b2 points to b1 that means, there is another reference to BetaObj1

a1.b1 指向 b1 意味着,有对 BetaObj1 的引用 a1.b2 指向 b1 意味着,还有另一个对 BetaObj1 的引用

(At this point there are 3 references to BetaObj1)

(此时有 3 个对 BetaObj1 的引用)

a2.b2 points to b2 that means, there is reference to BetaOBj2

a2.b2 指向 b2 这意味着,有对 BetaOBj2 的引用

(At this point there are 2 references to BetaObj2)

(此时有 2 个对 BetaObj2 的引用)

a1=null;makes AlphaObj1 eligible for GC

a1=null;使 AlphaObj1 有资格进行 GC

b1=null;makes BetaObj1 reference count to 2, so this object is not eligible for GC

b1=null;使 BetaObj1 引用计数为 2,因此该对象不符合 GC 条件

b2=null;makes BetaObj2 reference count to 1, so this object is not eligible for GC.

b2=null;使 BetaObj2 引用计数为 1,因此该对象不符合 GC 条件。

回答by tibtof

  • b2is not available for gc because there is still a reference a2.b2to it
  • b1is not available for gc because Alpha.b1holds a reference to it (Alpha.b1is static, don't be confused because it's set using a1.b1)
  • b2对 gc 不可用,因为仍有a2.b2对它的引用
  • b1对 gc 不可用,因为Alpha.b1持有对它的引用(Alpha.b1是静态的,不要混淆,因为它是使用设置的a1.b1

回答by Daniel Fischer

You ought to get a NullPointerExceptionhere:

你应该在NullPointerException这里得到一个:

System.out.println(" Line 1    " + " a1   "  + a1.b1);
System.out.println(" Line 2    " + " a1   "  + a1.b2);

At that point, a1was already set to null, so accessing its member b2can't work since it doesn't refer to an object anymore. (Accessing the static b1works since that only requires the class, not an instance.)

那时,a1已经设置为null,因此b2无法访问其成员,因为它不再引用对象。(访问静态b1作品,因为它只需要类,而不是实例。)

As you can see a1 , b1 and b2 were made NULL hence this is making objects to be available for garbage collection.

如您所见, a1 、 b1 和 b2 被设为 NULL,因此这使得对象可用于垃圾收集。

No, you set some references to these objects to null, while other references to those objects exist, as is the case for b1and b2, these objects cannot be collected yet.

不,你设置一些引用这些对象null,而对这些对象的其他引用存在,因为是的情况下b1b2,这些对象目前还无法收集。

回答by Peter Lawrey

There are several misconceptions here

这里有几个误解

  • The GC only runs when it needs to. To perform a GC more often than needed would be doing work it doesn't need to.
  • a1.b1is actually Alpha.b1as the instance is not important and can even be nullusing al.b1is plain confusing.
  • a1.b2should throw a NullPointerException as a1 is null.
  • Alpha.b1is set but not cleared anywhere so the object it referenced is not eligible for cleanup. The other objects could be cleaned up but without calling System.gc();explicitly, its is highly unlikely it need to be run at the point you might expect.
  • a1is cleared but a2is not so it won't be cleaned up (until the method returns)
  • GC 仅在需要时运行。比需要更频繁地执行 GC 将做它不需要的工作。
  • a1.b1实际上是Alpha.b1因为实例并不重要,甚至可以null使用al.b1也很容易混淆。
  • a1.b2应该像 a1 一样抛出 NullPointerException 异常null
  • Alpha.b1已设置但未在任何地方清除,因此它引用的对象不符合清理条件。其他对象可以被清理,但没有System.gc();显式调用,它极不可能需要在您可能期望的点运行。
  • a1被清除但a2不是所以它不会被清除(直到方法返回)

回答by AKHY

Garbage Collection Example

垃圾收集示例

public class GarbageCollection {

    public static void main(String s[]) throws Exception  {
          Runtime rs =  Runtime.getRuntime();
          System.out.println("Free memory in JVM before Garbage Collection = "+rs.freeMemory());
          rs.gc();
          System.out.println("Free memory in JVM after Garbage Collection = "+rs.freeMemory());
       }
}

Program Output:

程序输出:

Free memory in JVM before Garbage Collection = 62767488

垃圾回收前 JVM 中的可用内存 = 62767488

Free memory in JVM after Garbage Collection = 62854120

垃圾收集后 JVM 中的可用内存 = 62854120