Think in java 笔记之 finalize() 函数

1. java垃圾收集机制概述

  Java用new关键字生成的对象放在堆空间中,引用句柄则放在栈空间中。一个对象可以有多个引用。由于垃圾收集器的存在,对象是没有作用域的,引用句柄才有作用域。所以,当该对象的最后一个引用的作用域结束,或者该对象的最后一个引用指向了另一个对象或null,也就是说当该对象已经没有被任何引用句柄所引用的时候,该对象就可以被java垃圾收集器所回收了。回收发生的时间是不确定的,不过可以调用gc()方法通知jvm回收垃圾。

2. finalize()方法

  它是object类的一个protected方法,在垃圾收集器回收该对象之前调用自己。

3. finalize()的调用

程序退出时;

显示调用时;

我们来讨论最重要的第三种:

java垃圾收集器在回收这个对象之前,将会调用这个对象的finalize()方法,一旦垃圾收集器准备好释放对象占用的存储空间,它首先调用finalize(),而且只有在下一次垃圾收集过程中,才会真正回收对象的内存。所以如果使用finalize(),就可以在垃圾收集期间进行一些重要的清除或清扫工作。(该处引用了Think in java中的一句话)。程序验证如下

package chapter.one;

public class Garbage
{
    @SuppressWarnings("deprecation")
    public static void main(String[] args) {
        if(args.length == 0)
        {
            System.err.println("Usage: \n" +"java Garbage before\n or:\n" +
            "java Garbage after");
            return;
        }

        //循环
        while(!Chair.f)
        {

            new Chair();
            new String("To take up space");
        }

        System.out.println("After all Chairs have been created:\n" +
                "total created = " + Chair.created +
                ", total finalized = " + Chair.finalized);

        if(args[0].equals("before"))
        {
            System.out.println("gc():");
            System.gc();
            System.out.println("runFinalization():");
            System.runFinalization();
        }

        System.out.println("bye!");
        if(args[0].equals("after"))
        System.runFinalizersOnExit(true);
    }
}

class Chair
{
    static boolean gcrun = false;
    static boolean f = false;
    static int created = 0;        //static用来统计创建的对象的个数
    static int finalized = 0;
    int i;

    Chair()
    {
        i = ++created;
        if(created == 47)
        System.out.println("Created 47");
    }

    //在垃圾回收之前调用
    @Override
    protected void finalize()
    {
//        gcrun的标记来指出垃圾收集器是否已经开始运行。
        if(!gcrun)
        {
            gcrun = true;
            System.out.println("Beginning to finalize after " +created +
                    " Chairs have been created");
        }
        //当f等于true的时候main函数应该停止对象的生成
        if(i == 47)
        {
            System.out.println("Finalizing Chair #47, " +
            "Setting flag to stop Chair creation");
            f = true;
        }

        finalized++;
        if(finalized >= created)
            System.out.println("All " + finalized + " finalized");
    }
}

运行效果:

Created 47
Beginning to finalize after 231850 Chairs have been created
Finalizing Chair #47, Setting flag to stop Chair creation
After all Chairs have been created:
total created = 2476964, total finalized = 1403452
gc():
runFinalization():
bye!

4. 为何要定义finalize()方法

  有时当撤消一个对象时,需要完成一些操作。例如,如果一个对象正在处理的是非Java 资源,如文件句柄或window 字符字体(该处示例以后补充),这时你要确认在一个对象被撤消以前要保证这些资源被释放。为处理这样的状况,Java 提供了被称为收尾(finalization )的机制。

(因为无法保证是什么时候,所以不提倡使用这个方法)使用该机制你可以定义一些特殊的操作,这些操作在一个对象将要被垃圾回收程序释放时执行。 
要给一个类增加收尾(finalizer ),你只要定义finalize ( ) 方法即可。Java 回收该类的一个对象时,就会调用这个方法。

总的来说,就是你想在干对象被回收之前做点儿什么事儿,那么将该事件写进finalize()函数中,而且这件事儿还得不是特别急。  

5. finalize()方法并不是万能的

  比如当对象占用了很多的系统资源的时候。这个时候就不能放其不管而等着垃圾回收器来回收了,因为垃圾回收的发生------得看jvm的心情,因此,你的函数就应该提供其它的方法在该对象的引用清零之前,回收该对象所占用的资源。

原文地址:https://www.cnblogs.com/long-ge-ge/p/8151290.html

时间: 2024-10-12 15:19:07

Think in java 笔记之 finalize() 函数的相关文章

java的finalize()函数

在说明finalize()的用法之前要树立有关于java垃圾回收器几个观点: "对象可以不被垃圾回收" : java的垃圾回收遵循一个特点, 就是能不回收就不会回收.只要程序的内存没有达到即将用完的地步, 对象占用的空间就不会被释放.因为如果程序正常结束了,而且垃圾回收器没有释放申请的内存, 那么随着程序的正常退出, 申请的内存会自动交还给操作系统; 而且垃圾回收本身就需要付出代价, 是有一定开销的, 如果不使用,就不会存在这一部分的开销. 垃圾回收只能回收内存, 而且只能回收内存中由

java笔记整理

Java 笔记整理 包含内容     Unix Java 基础, 数据库(Oracle jdbc Hibernate pl/sql), web, JSP, Struts, Ajax Spring, Ejb, java和模式 Linux/Unix笔记 inode :存储编号(地址) ls -k:查看磁盘分区 ls -li:显示当前文件的inode号. 目录的大小跟文件的大小有关,跟目录里的文件(目录)数量无关. 一行多个命令的话,中间用分号分开.如:pwd;cal;date last | grep

JAVA 笔记 七

JAVA笔记七 this:就代表本类的对象,this代表它所在函数所属对象的引用简单说:那个对象在调用this所在的函数,this就代表那个对象静态:static 用法:是一个修饰符,用于修饰成员(成员变量,成员函数)当成员被静态修饰后,就多了一个调用方式,除了可以被对象调用外,还可以直接被类名调用.类名.静态成员static特点1.随着类的加载而加载2.优先于的对象存在3.被所有对象所共享4.可以直接被类名所调用实例变量和类变量的区别:1.存放位置. 类变量随着类的加载而存在与方法区中. 实例

4.5-全栈Java笔记:垃圾回收机制

垃圾回收机制(Garbage  Collection) Java引入了垃圾回收机制,令C++程序员最头疼的内存管理问题迎刃而解.JAVA程序员可以将更多的精力放到业务逻辑上而不是内存管理工作上,大大的提高了开发效率. 垃圾回收原理和算法 1)内存管理 Java的内存管理很大程度指的就是对象的管理,其中包括对象空间的分配和释放. 对象空间的分配:使用new关键字创建对象即可 对象空间的释放:将对象赋值null即可.垃圾回收器将负责回收所有"不可达"对象的内存空间. 2)垃圾回收过程 任何

4.8-全栈Java笔记:包机制

包机制是java中管理类的重要手段. 开发中,我们会遇到大量同名的类,通过包我们很容易对解决类重名的问题,也可以实现对类的有效管理. 包对于类,相当于,文件夹对于文件的作用. package 我们通过package实现对类的管理,package的使用有两个要点: 1.通常是类的第一句非注释性语句. 2.包名:域名倒着写即可,再加上模块名,便于内部管理类. [示例1]package的命名举例 com.sun.test; com.oracle.test; com.bjsxt.gao.test; co

4.2-全栈Java笔记:对象和类的概念及定义

对象和类的概念 我们人认识世界,其实就是面向对象的.大家眼里都是一个个对象,要不怎么老说搞对象搞对象啊.比如现在让大家认识一下"天使"这个新事物,天使大家没见过吧,怎么样认识呢?最好的办法就是,给你们面前摆4个天使,带翅膀的美女,让大家看,看完以后,即使我不说,大家下一次是不是就都认识天使了. 但是,看完10个天使后,我们总要总结一下,什么样的东东才算天使?天使是无数的,总有没见过的!所以必须总结抽象,便于认识未知事物!总结的过程就是抽象的过程. 小时候,我们学自然数时怎么定义的?像1

Java 笔记(8)

JSP 技术 day8 JSP语法 + EL + JSTL day9 案例 2-3 个 综合小案例 day10 Servlet+JSP 综合练习 为什么sun推出 JSP技术 ? Servlet 生成网页比较复杂,本身不支持HTML语法,html代码需要通过response输出流输出,JSP支持HTML语法,生成HTML方便. JSP技术与Servlet 技术区别和关系? JSP和Servlet技术都是用来动态生成网页的,Servlet不支持HTML语法,生成网页麻烦,JSP支持HTML语法,生

Java笔记(9)

JSP 存在两种 开发模式 Model1 : JSP + JavaBean * 不适合开发业务逻辑特别复杂web应用 ----- 业务逻辑复杂,控制代码多,而在jsp中编写控制代码,十分不便 Model2 : JSP + JavaBean + Servlet 符合MVC设计模式 JSP(View视图功能):负责页面显示 JavaBean(Model 模型功能):负责数据封装和处理 Servlet(Controller 控制器功能):连接模型和视图,对整个业务流程进行控制,调用JavaBean封装

Java笔记(10)

第一天 ----- 第十天 知识点复习 day1 XML 语法和两种约束技术 1.XML语法写法.规范: 根元素必须唯一.元素名称与属性名称不能以数字开始.元素标记必须结束.元素不能交叉嵌套.属性值必须加引号(双引号.单引号) ----- 考试:排错 2.CDATA块 与 特殊字符转义在 使用上区别 ? <book> <p>标记的作用 </book>  ----- 标记内容 <p> 是一个特殊内容 CDATA : <book> <![CDA