JavaRush /Java 博客 /Random-ZH /Java 中的垃圾收集器
Diana
第 41 级

Java 中的垃圾收集器

已在 Random-ZH 群组中发布

垃圾收集器(内存回收器)的行为线

Java 程序员不需要监视内存分配,因为垃圾收集器会自动管理内存。垃圾收集器由 Java 虚拟机 (JVM) 运行。垃圾收集器是一个低优先级进程,它定期运行并释放不再需要的对象使用的内存。不同的 JVM 有不同的垃圾收集算法。使用了多种算法,例如:引用计数算法或标记和抓取算法。垃圾收集 - 1

在 Java 中运行垃圾收集器

当可用内存较低时,JVM 通常会运行垃圾收集器。但垃圾收集器的运行并不能保证总是有足够的空闲内存。如果恢复后仍然没有足够的内存,JVM 会抛出 OutOfMemoryError 异常。请注意,JVM 在抛出异常之前必须至少运行一次垃圾收集器。您可以请求垃圾收集器在 Java 中运行,但不能强制执行此操作。

请求运行垃圾收集器

要发出请求,您可以调用以下方法之一:
System.gc()
Runtime.getRuntime().gc()

适合运行垃圾收集器

当对象不再可供活动流使用时,必须将其丢弃。一个物体可能会在不同的情况下被处置:
  • 如果引用某个对象的引用类型变量被设置为“0”,并且没有其他引用对该对象进行处理,则必须释放该对象。
  • 如果创建引用一个对象的引用类型变量来引用另一个对象,并且没有其他引用对该对象进行处理,则必须释放该对象。
  • 当方法退出时,在方法中本地创建的对象将被丢弃,除非它们是从该方法导出的(即作为异常返回或抛出)。
  • 如果没有一个对象可供活动线程使用,则相互引用的对象可能会被处置。
让我们看一个例子:
public class TestGC
  {
    public static void main(String [] args)
    {
      Object o1 = new Integer(3);               // Line 1
      Object o2 = new String("Tutorial");       // Line 2
      o1 = o2;                                  // Line 3
      o2 = null;                                // Line 4
      // Rest of the code here
    }
  }
在此示例中Integer,最初由 o1 引用的对象(整数)可以在第 3 行之后处理,因为 o1 现在引用该对象String(字符串)。即使创建 o2 来引用 null,该对象String(字符串)也是不可回收的,因为 o1 引用了它。

最终确定

finalize()Java 技术允许您在垃圾收集器从内存中检索对象之前使用方法(finalize) 进行必要的清理。当垃圾收集器确定不再有对该对象的引用时,垃圾收集器会对该对象调用此方法。这是在 class 中描述的Object,这意味着它被所有类继承。子类重写该方法finalize()以将其自身从系统资源中释放出来或进行另一次清理:
protected void finalize() throws Throwable
如果方法抛出未注册的异常finalize(),则该异常将被忽略并且该对象的终结将停止。该方法finalize()在对象的生命周期内只会被调用一次。可以对finalize()任何物体使用某种方法来保护其免遭处置。但在这种情况下,垃圾收集器不再finalize()为此对象激活。finalize()在对象被垃圾收集之前,该方法始终会被调用一次。然而,对于给定对象,该方法finalize()可能不会在其存在的整个持续时间内被激活,因为它可能不会受到处置。

概括

在本节中,我们研究了垃圾收集过程,这是 Java 语言中的一种内存管理技术。不能强制垃圾收集。我们了解了使对象符合回收条件的不同方法,并了解了finalize()在垃圾收集器回收对象之前调用该方法。

锻炼

问: 第 7 行之后有多少物品将被处置?
public class TutorialGC
  {
    public static void main(String [] args)
    {
      Object a = new Integer(100);  // Line1
      Object b = new Long(100);     // Line2
      Object c = new String("100"); // Line3
      a = null;                     // Line4
      a = c;                        // Line5
      c = b;                        // Line6
      b = a;                        // Line7
      // Rest of the code here
    }
  }
答案选项: A. 0 B. 1 C. 2 D. 3 E. 代码无法编译 正确选项: B 说明:在第 1、2、3 行创建的三个对象中,只有该对象Integer必须在第 7 行末尾。最初引用对象的变量引用 a在第 5 行Integer引用了该对象。因此,必须在第 5 行之后处理该对象,因为没有引用它的变量。变量和引用第6行和第7行中的对象和对象,因此它们是不可回收的。 StringIntegerbcStringLong
评论
TO VIEW ALL COMMENTS OR TO MAKE A COMMENT,
GO TO FULL VERSION