【问题标题】:Java object Garbage collection by JVMJVM的Java对象垃圾收集
【发布时间】:2013-10-03 15:27:33
【问题描述】:

每个 java 开发者都知道 java 对象 在不再使用时会被垃圾回收。 我想知道 JVM 如何识别必须选择哪个对象进行垃圾收集。 (例如,如果我有 10 个对象。如果有 2 个对象被垃圾收集,那么 10 个对象中 jvm 如何找到这两个对象)。

JVM 使用 "mark and sweep" 算法(如果我是对的)。

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)变为空,但是在堆上分配的内存会发生什么情况?会被释放吗?

【问题讨论】:

    标签: java jvm


    【解决方案1】:

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

    【讨论】:

      【解决方案2】:

      这里已经相当简洁地介绍了:http://www.brpreiss.com/books/opus5/html/page424.html

      标记和清除算法称为跟踪垃圾收集器 因为 is 会追踪所有对象的集合 程序可以直接或间接访问。

      程序可以直接访问的对象是那些 由处理器堆栈上的局部变量以及由 任何引用对象的静态变量。在垃圾的背景下 集合,这些变量称为根。一个对象是 如果它被其他某个字段引用,则可以间接访问 (直接或间接)可访问的对象。

      因此,当您执行s1=null; 时,您将断开根,并且相应的实例有资格被收集。

      实际的“收集”(释放堆)发生在 GC 实际执行时。至于何时发生这种情况,并没有一个万能的答案。见What the frequency of the Garbage Collection in Java?

      【讨论】:

        【解决方案3】:

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

        【讨论】:

        • 如果我将引用 (s1,s2) 设为空。 JVM 如何识别某些对象可用于 GC。
        • @Manu 当没有活动线程可以访问一个对象时,它就有资格进行垃圾回收,Java GC 知道这一点。而且 GC 不经常运行它几乎不运行。
        【解决方案4】:

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

        【讨论】:

          【解决方案5】:

          如果无法从任何活动线程或任何静态引用访问对象,则该对象符合垃圾收集或 GC 的条件

          SEE HERE

          【讨论】:

            【解决方案6】:

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

            它会被释放吗?

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

            【讨论】:

              猜你喜欢
              • 2012-07-09
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 1970-01-01
              • 2011-02-23
              • 2010-11-08
              • 1970-01-01
              相关资源
              最近更新 更多