繁体   English   中英

JVM的Java对象垃圾收集

[英]Java object Garbage collection by JVM

每个Java开发人员都知道,不再使用Java对象时将对其进行垃圾回收。 我想知道JVM如何确定必须选择哪个对象进行垃圾收集。 (例如,如果我有10个对象。如果10个对象中有2个对象被垃圾回收,则jvm如何找到两个对象)。

JVM使用“标记和清除”算法(如果正确的话)。

1)例如我在下面提供了字符串对象方案

  class Sample{

     public static void main(Strings args[]){
      String s1=new String("10");
      String s2=new String("20");
      String s3=new String("30");
      String s4=new String("40");
      String s5=new String("50");
      String s6=new String("60");
      String s7=new String("70"); 

        s1=null; //now s1 is eligible for gc collection
        s2=null; //now s2 is eligible for collection


 }
}

//现在s1和s2可以进行gc收集了。如果我明确地将null引用(s1,s2)设为null,那么堆上分配的内存又如何呢? 会被释放吗?

实际上什么也没发生。 s1和s2所使用的内存仅在GC开始工作时才会被重用,并且仅在JVM决定时才会发生,并且可能永远不会发生。 在您的情况下,GC几乎不会启动。

为任何引用分配null不会释放内存。 它仅使引用可用于使用垃圾收集器删除。 意味着现在运行垃圾回收器时,此引用分配的内存可以释放。

此处的内容非常简洁: http//www.brpreiss.com/books/opus5/html/page424.html

标记清除算法称为跟踪垃圾收集器,因为它可以跟踪程序直接或间接访问的对象的整个集合。

程序可以直接访问的对象是处理器堆栈上的局部变量以及引用该对象的任何静态变量所引用的那些对象。 在垃圾回收的上下文中,这些变量称为roots。 如果某个对象被某个其他(直接或间接)可访问对象中的字段引用,则该对象是间接可访问的。

因此,当您执行s1=null; 您将断开根连接,相应的实例将有资格进行收集。

当GC实际执行时,发生实际的“收集”(释放堆)。 至于确切何时发生,还没有一个万能的答案。 请参阅Java中垃圾回收的频率是多少?

如果任何活动线程无法以任何方式访问该对象,则该对象将有资格进行垃圾回收。 但是,GC不能保证运行,因为它取决于JVM内部逻辑和算法。 通常,它发生在JVM认为有时间清理一些内存使用情况时。 在您的情况下,s1和s2有资格被GC,但我们无法确定何时会发生。

如果无法从任何活动线程或任何静态引用中访问对象,则该对象有资格进行垃圾回收或垃圾回收

看这里

当Java对象的引用计数为0时,就有资格进行垃圾回收。引用计数为0表示“该特定对象未被任何变量引用,因此无法再使用它”。 垃圾收集器在第一遍中标记所有引用计数为0的对象,在第二遍中清除所有标记的对象。 因此,它是标记和清除算法。

会被释放吗?

这取决于垃圾收集器,当您将s1和s2设为null后重新运行垃圾收集器时,它们将有资格进行垃圾收集。 但是,将引用设为null不会立即从内存中释放对象

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM