大家都知道使用new运算符在内存中创建了一个对象。构造函数用于初始化该对象的属性。当不再需要某个对象时,必须将其从内存中删除,以便该内存可以重用于其他对象。从内存中删除不需要的对象或放弃的对象称为垃圾回收(GC)。在像C ++这样的语言中,GC是使用析构函数手动执行的。

但是,java中没有析构函数。在java中,存在更好的处理垃圾收集的机制。您无需显式删除不需要的对象。JVM为您完成此任务。JVM隐式地从内存中清除被遗弃的对象。

在继续java中的垃圾收集之前,让我们看一下Object类的finalize()方法。

Java中的finalize方法

finalize()方法是java.lang.Object类的受保护和非静态方法。你可以在java中创建的所有对象中使用此方法。此方法用于在对象从内存中删除之前对对象执行某些最终操作或清理操作。您可以覆盖finalize()方法,以便在销毁对象之前保留要执行的操作。这是finalize()方法的一般形式。

protected void finalize() throws Throwable

{

//Keep some resource closing operations here

}

Java中的垃圾收集

无论何时运行java程序,JVM都会创建三个线程。1)主线程;2)线程调度器;3)垃圾收集器线程。在这三个线程中,主线程是用户线程,剩下的两个是在后台运行的守护线程。

主线程的任务是执行main()方法。线程调度程序的任务是调度线程。垃圾收集器线程的任务是从堆内存中清除废弃的对象。被遗弃的对象或死对象是那些没有实时引用的对象。垃圾收集器线程在扫除一个废弃的对象之前,它调用该对象的finalize()方法。执行finalize()方法后,对象将从内存中销毁。这意味着在从内存中销毁对象之前,执行在finalize()方法中保留的清理操作。

只要对象被放弃,垃圾收集器线程就不会进入堆内存。它偶尔出现在堆内存中,当时如果它看到任何被遗弃的对象,它会在调用finalize()方法之后扫除这些对象。垃圾收集器线程仅对一个对象调用finalize()方法一次。

让我们讨论一些关于垃圾收集和finalize()方法的有趣观点。

关于垃圾收集的一些有趣点和Java中的finalize()方法

1)在某些情况下,垃圾收集器线程根本不调用finalize()方法。例如,当我在系统中执行以下程序时,A类的finalize()方法根本没有执行。

class A

{

int i = 50;

@Override

protected void finalize() throws Throwable

{

System.out.println("From Finalize Method");

}

}

public class Test

{

public static void main(String[] args)

{

//Creating two instances of class A

A a1 = new A();

A a2 = new A();

//Assigning a2 to a1

a1 = a2;

//Now both a1 and a2 will be pointing to same object

//An object earlier referred by a1 will become abandoned

System.out.println("done");

}

}

2)可以使用 Runtime.getRuntime().runFinalization() 或 Runtime.runFinalizersOnExit(true)强制执行finalize()方法。但是,这两种方法都有缺点。Runtime.getRuntime().runFinalization() 尽最大努力执行finalize()方法,但不保证finalize()方法一定被执行。在JDK中不推荐使用Runtime.runFinalizersOnExit(true) ,因为有时它也会在仍然活跃的对象上运行finalize()方法。

class A

{

int i = 50;

@Override

protected void finalize() throws Throwable

{

System.out.println("From Finalize Method");

}

}

public class Test

{

public static void main(String[] args)

{

//Creating two instances of class A

A a1 = new A();

A a2 = new A();

//Assigning a2 to a1

a1 = a2;

//Making finalize() method to execute forcefully

Runtime.getRuntime().runFinalization();

System.out.println("done");

}

}

3)可以使用 System.gc()或RunTime.getRunTime().gc()进行显式地调用垃圾收集。同样,它只是对垃圾收集器的请求而不是命令,垃圾收集器可以满足此要求。

class A

{

int i;

public A(int i)

{

this.i = i;

}

@Override

protected void finalize() throws Throwable

{

System.out.println("From Finalize Method, i = "+i);

}

}

public class Test

{

public static void main(String[] args)

{

//Creating two instances of class A

A a1 = new A(10);

A a2 = new A(20);

//Assigning a2 to a1

a1 = a2;

//Now both a1 and a2 will be pointing same object

//An object earlier referred by a1 will become abandoned

//Calling garbage collector thread explicitly

System.gc(); //OR call Runtime.getRuntime().gc();

System.out.println("done");

}

}

4) finalize()方法不像构造函数那样是链式调用。对于子类的finalize()方法内部的超类finalize()方法没有调用语句。您需要显式调用超类finalize()方法。

protected void finalize() throws Throwable

{

System.out.println("From Finalize Method");

//Calling super class finalize() method explicitly

super.finalize();

}

5) finalize()方法中发生的异常不会传播。它们会被垃圾收集器忽略。

6)在丢弃对象之前,可以在对象上显式调用finalize()方法。调用时,只对对象执行finalize()方法中保持对象操作,对象不会从内存中销毁。

class A

{

int i;

public A(int i)

{

this.i = i;

}

@Override

protected void finalize() throws Throwable

{

System.out.println("From Finalize Method, i = "+i);

//Calling super class finalize() method explicitly

super.finalize();

}

}

public class Test

{

public static void main(String[] args)

{

//Creating two instances of class A

A a1 = new A(10);

A a2 = new A(20);

//Calling finalize() method of a1 before it is abandoned

try

{

a1.finalize();

}

catch (Throwable e)

{

e.printStackTrace();

}

//Assigning a2 to a1

a1 = a2;

//Now both a1 and a2 will be pointing same object

//An object earlier referred by a1 will become abandoned

System.out.println("done");

}

}

7)丢弃对象的finalize()方法仅由垃圾收集器线程调用一次。GC忽略开发人员在对象上调用的finalize()方法。

参考引用

java手动调用finalize,Java中的垃圾收集与finalize方法相关推荐

  1. java skip函数_【Java必修课】图说Stream中的skip()和limit()方法及组合使用

    1 简介 本文将讲解Java 8 Stream中的两个方法:skip()和limit().这两个方法是Stream很常用的,不仅各自会被高频使用,还可以组合出现,并能实现一些小功能,如subList和 ...

  2. java e.getmessage() null,浅谈Java异常的Exception e中的egetMessage()和toString()方法的区别...

    Exception e中e的getMessage()和toString()方法的区别: 示例代码1: public class TestInfo { private static String str ...

  3. JAVA 通过value获取Map中key的三种方法

    JAVA 通过value获取Map中key的三种方法 简介 方法描述 循环法 Stream方法 Apache Commons Collections的BidiMap 总结 简介 我们都知道Map是存放 ...

  4. Java JNI调用C语言中的函数

    1.调用无参函数 java code public class JNITest {static {/*加载*/System.loadLibrary("mynative");}pub ...

  5. JAVA加载JAR包并调用JAR包中某个类的某个方法

    package com.example; public class Runner implements Runnable{ public void run(String name) {System.o ...

  6. java args例子_Spring AOP中使用args表达式的方法示例

    本文实例讲述了Spring AOP中使用args表达式的方法.分享给大家供大家参考,具体如下: 一 配置 xmlns:xsi="http://www.w3.org/2001/XMLSchem ...

  7. java 数组 length 减少_java中数组有没有length()方法?string没有lenght()方法?

    java中数组有没有length()方法,求数组的长度可以使用数组的length属性. int length=arr.length;//求数组的长度 ------------------------- ...

  8. java定义private_java9开始——接口中可以定义private私有方法

    在传统的Java编程中,被广为人知的一个知识点是:java Interface接口中不能定义private私有方法.只允许我们定义public访问权限的方法.抽象方法或静态方法.但是从Java 9 开 ...

  9. 前端vue后端java,Vue调用后端java接口的实例代码_亦心_前端开发者

    前段时间 做了个学校的春萌项目,其中用到 先上后端接口代码: package controller; import net.sf.json.JSONObject; import util.DBUtil ...

最新文章

  1. EditText和TextView出现中文、英文等string串的排版问题
  2. Mysql实战:主从同步
  3. python自定义函数详解_python基础教程之自定义函数介绍
  4. 数字图像处理——添加高斯噪声椒盐噪声
  5. php 5.5.1,PHP5.3.1 不再支持ISAPI
  6. Detectron2和MMDetection的学习笔记
  7. 为您详细比较三个 CSS 预处理器(框架):Sass、LESS 和 Stylus
  8. ssm留学生交流互动论坛网站计算机毕业设计
  9. 跨界创新属于这个时代的颠覆思想
  10. GitHub上收录400余篇任正非的讲话稿
  11. 贝叶斯统计之三种信息
  12. 凯云软件测试项目管理系统系统描述
  13. s3c2440移植Linux内核,移植Linux-3.4.2内核到S3C2440
  14. Windows10系统安装postgreSQL出错解决方法
  15. Python解析GPGGA报文_统计数据完整率
  16. 7-40 到底是不是太胖了(10 分)
  17. 朗强HDMI视频拼接分割器
  18. 数据挖掘的10大算法我用大白话讲清楚了,新手一看就懂
  19. 显示器AutoColor原理(TSUM系列芯片)
  20. 什么是延迟?如何在直播中实现低延迟

热门文章

  1. 不畏困难,直面挫折,维乐回顾环台之旅
  2. js修改css hover样式,JS实现css hover操作的方法示例
  3. 浅谈linux学习路线
  4. 30s入门Kotlin数组
  5. css设置背景图片等比例铺满整个页面
  6. Android设备网络数据流量统计
  7. C++实现古典密码-凯撒密码加密解密算法
  8. Windows Server 2003广州虚拟主机网DVD版
  9. React在线编辑简历
  10. java实现拖动框排序_拖拽排序后端设计与实现