千家信息网

Java如何实现垃圾回收机制

发表于:2026-11-03 作者:千家信息网编辑
千家信息网最后更新 2026年11月03日,这篇文章将为大家详细讲解有关Java如何实现垃圾回收机制,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。1、介绍在 C/C++ 中,程序员负责对象的创建和销毁。通常程
千家信息网最后更新 2026年11月03日Java如何实现垃圾回收机制

这篇文章将为大家详细讲解有关Java如何实现垃圾回收机制,小编觉得挺实用的,因此分享给大家做个参考,希望大家阅读完这篇文章后可以有所收获。

    1、介绍

    • 在 C/C++ 中,程序员负责对象的创建和销毁。通常程序员会忽略无用对象的销毁。由于这种疏忽,在某些时候,为了创建新对象,可能没有足够的内存可用,整个程序将异常终止,

    • Java 中,导致OutOfMemoryErrors。程序员不需要关心所有不再使用的对象。

    • 垃圾回收机制自动销毁这些对象。垃圾回收机制是守护线程的最佳示例,因为它始终在后台运行。

    • 垃圾回收机制的主要目标是通过销毁无法访问的对象来释放堆内存。

    2、重要条款

    2.1 无法访问的对象

    如果一个对象不包含对它的任何引用,则称其为无法访问的对象。另请注意,属于隔离岛的对象也无法访问。

    Integer i = new Integer(4);// 新的 Integer 对象可通过 'i' 中的引用访问i = null;// Integer 对象不再可用。

    2.2 垃圾回收的资格

    如果对象无法访问,则称该对象有资格进行 GC(垃圾回收)。在上图中,在i = null 之后; 堆区域中的整数对象 4 有资格进行垃圾回收。

    3、使对象符合 GC 条件的方法

    即使程序员不负责销毁无用的对象,但如果不再需要,强烈建议使对象不可访问(因此有资格进行 GC)。

    通常有四种不同的方法可以使对象适合垃圾回收。

    • 取消引用变量

    • 重新分配引用变量

    • 在方法内部创建的对象

    • 隔离岛

    以上所有带有示例的方法都在单独的文章中讨论:如何使对象符合垃圾收集条件

    4、请求JVM运行垃圾收集器的方式

    • 一旦我们使对象符合垃圾收集条件,垃圾收集器可能不会立即销毁它。每当 JVM 运行垃圾收集器程序时,只会销毁对象。但是当JVM运行Garbage Collector时,我们无法预料。

    • 我们还可以请求 JVM 运行垃圾收集器。有两种方法可以做到:

    使用System.gc() 方法:系统类包含静态方法gc() 用于请求 JVM 运行垃圾收集器。
    使用Runtime.getRuntime().gc() 方法:运行时类允许应用程序与运行应用程序的 JVM 交互。因此,通过使用其 gc() 方法,我们可以请求 JVM 运行垃圾收集器。

    // 演示请求 JVM 运行垃圾收集器的 Java 程序public class Test{ public static void main(String[] args) throws InterruptedException {  Test t1 = new Test();  Test t2 = new Test();    // 取消引用变量  t1 = null;    // 请求 JVM 来运行垃圾收集器  System.gc();    // 取消引用变量  t2 = null;    // 请求 JVM 来运行垃圾收集器  Runtime.getRuntime().gc();  }  @Override // 在垃圾回收之前,在对象上调用一次 finalize 方法 protected void finalize() throws Throwable {  System.out.println("垃圾收集器调用");  System.out.println("对象垃圾收集:" + this); }}

    输出:

    垃圾收集器调用
    对象垃圾收集:haiyong.Test@7ad74083
    垃圾收集器调用
    对象垃圾收集:haiyong.Test@7410a1a9

    • 不能保证以上两种方法中的任何一种都一定会运行垃圾收集器。

    • 调用System.gc() 等效于调用:Runtime.getRuntime().gc()

    就在销毁对象之前,垃圾收集器调用对象的finalize() 方法来执行清理活动。一旦finalize() 方法完成,垃圾收集器就会销毁该对象。

    finalize() 方法存在于具有以下原型的Object 类中。

    protected void finalize() throws Throwable

    根据我们的要求,我们可以覆盖finalize() 方法来执行我们的清理活动,例如关闭数据库连接。

    • 垃圾收集器而不是JVM调用的finalize() 方法。虽然垃圾收集器是JVM的模块之一。

    • 对象类 finalize() 方法有空实现,因此建议覆盖finalize() 方法来处理系统资源或执行其他清理。

    • 对于任何给定的对象,finalize() 方法永远不会被多次调用。

    • 如果finalize() 方法抛出未捕获的异常,则忽略该异常并终止该对象的终结。

    有关finalize() 方法的示例,请参阅Java 程序的输出第十套之垃圾收集

    5、举例

    使用垃圾收集器的概念。

    假设你去字节跳动实习,他们告诉你写一个程序,计算在公司工作的员工人数(不包括实习生)。要制作这个程序,你必须使用垃圾收集器的概念。

    这是您在公司获得的实际任务:-

    问: 编写一个程序来创建一个名为 Employee 的类,该类具有以下数据成员。

    • 一个ID,用于存储分配给每个员工的唯一ID。

    • 员工姓名。

    • 员工年龄。

    另外,提供以下方法-

    • 用于初始化名称和年龄的参数化构造函数。ID 应在此构造函数中初始化。

    • 显示 ID、姓名和年龄的方法 show() 。

    • 显示下一个员工的 ID 的方法 showNextId() 。

    现在对垃圾回收机制不了解的初学者可能会这样编写代码:

    //计算在公司工作的员工人数的程序class Employee{ private int ID; private String name; private int age; private static int nextId=1; //它是静态的,因为它在所有对象之间保持通用并由所有对象共享 public Employee(String name,int age) {  this.name = name;  this.age = age;  this.ID = nextId++; } public void show() {  System.out.println  ("Id="+ID+"\nName="+name+"\nAge="+age); } public void showNextId() {  System.out.println  ("Next employee id will be="+nextId); }}class UseEmployee{ public static void main(String []args) {  Employee E=new Employee("GFG1",33);  Employee F=new Employee("GFG2",45);  Employee G=new Employee("GFG3",25);  E.show();  F.show();  G.show();  E.showNextId();  F.showNextId();  G.showNextId();      { //这是保留所有实习生的子块。   Employee X=new Employee("GFG4",23);    Employee Y=new Employee("GFG5",21);   X.show();   Y.show();   X.showNextId();   Y.showNextId();  }  //这个大括号之后,X 和 Y 将被移除。因此现在它应该显示 nextId 为 4。  E.showNextId();//这一行的输出应该是 4,但它会给出 6 作为输出。 }}

    输出:

    现在获得正确的输出:

    现在垃圾收集器(gc)将看到 2 个空闲的对象。现在递减 nextId,gc(garbage collector) 只会在我们的程序员在我们的类中覆盖它时调用方法 finalize() 。如前所述,我们必须请求 gc(garbage collector) ,为此,我们必须在关闭子块的大括号之前编写以下 3 个步骤。

    • 将引用设置为 null(即 X = Y = null;)

    • 调用,System.gc() ;

    • 调用,System.runFinalization() ;

    现在计算员工人数的正确代码(不包括实习生)

    // 计算不包括实习生的员工人数的正确代码class Employee{ private int ID; private String name; private int age; private static int nextId=1; //它是静态的,因为它在所有对象之间保持通用并由所有对象共享 public Employee(String name,int age) {  this.name = name;  this.age = age;  this.ID = nextId++; } public void show() {  System.out.println  ("Id="+ID+"\nName="+name+"\nAge="+age); } public void showNextId() {  System.out.println  ("Next employee id will be="+nextId); } protected void finalize() {  --nextId;  //在这种情况下,gc 会为 2 个对象调用 finalize() 两次。 }}// 它是 Employee 类的右括号class UseEmployee{ public static void main(String []args) {  Employee E=new Employee("GFG1",33);  Employee F=new Employee("GFG2",45);  Employee G=new Employee("GFG3",25);  E.show();  F.show();  G.show();  E.showNextId();  F.showNextId();  G.showNextId();     {   //这是保留所有实习生的子块。   Employee X=new Employee("GFG4",23);    Employee Y=new Employee("GFG5",21);   X.show();   Y.show();   X.showNextId();   Y.showNextId();   X = Y = null;   System.gc();   System.runFinalization();  } E.showNextId(); }}

    输出:

    关于"Java如何实现垃圾回收机制"这篇文章就分享到这里了,希望以上内容可以对大家有一定的帮助,使各位可以学到更多知识,如果觉得文章不错,请把它分享出去让更多的人看到。

    对象 垃圾 方法 收集器 程序 运行 员工 输出 机制 实习 实习生 程序员 人数 变量 资格 代码 公司 年龄 括号 条件 数据库的安全要保护哪些东西 数据库安全各自的含义是什么 生产安全数据库录入 数据库的安全性及管理 数据库安全策略包含哪些 海淀数据库安全审计系统 建立农村房屋安全信息数据库 易用的数据库客户端支持安全管理 连接数据库失败ssl安全错误 数据库的锁怎样保障安全 云之行互联网科技 互联网科技工作委员会副主任毛军 互联网科技有限公司经营范围 互联网 科技公司 奇士达互联网科技 美国互联网黑科技 火传媒上海互联网科技 郑州华宇互联网科技 美国互联网前沿科技 联恩商钥互联网科技有限公司 山东吉时兔互联网科技有限公司 卫星互联网科技股票 现代科技和互联网有关系吗 西藏七维空间互联网科技有限公司 金融科技与互联网金融相同和不同 彤创互联网科技有限公司 广州有谷有贝互联网科技有限公司 吉林省码上互联网科技电话 万物互联网智能科技 如何强化互联网金融科技 科技创新与互联网经济 互联网 的科技创新 百单互联网科技有限公司 伴你行互联网科技有限公司 无锡溥仪互联网科技有限公司 海南科技产业互联网平台 云创客互联网科技公司 厦门比较好的科技互联网公司 互联网科技数字货币 知域互联网科技有限公司官网
    0