博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
finalize()及垃圾回收
阅读量:4630 次
发布时间:2019-06-09

本文共 1257 字,大约阅读时间需要 4 分钟。

整体认识

finalize()方法是一个与垃圾回收相关的方法(和C++中的析构函数有很大的区别),

finalize()方法不是用于垃圾回收,而是与垃圾回收相关

是Objecte类中的方法

finalize()方法的说明方式 : protected void finalize()throws Throwable

一个对象只能调用一次finalize()方法

深入认识finalize()

想要深入了解finalize()方法就要先对Jvm的堆内存的垃圾回收机制有一个认识;

JVM采用垃圾回收算法是可达性分析算法,下面先了解一下可达性算法:

可达性算法可用用下面的一个树形图来认识,若内存与GC root有连接则该内存是不可被回收的,若相应的内存与GC root没有连接的通路那么该内存就是可回收的(但不一定被回收)

 

 

a  b  c 与GC root有连接的通路,所以他们三个都是不可回收的,而d e与GC Roots没有通路相连,所以他们是可被回收的,当然GC Roots的选取是有要求的

可作为GC Roots的对象:

1、 虚拟机栈(java 方法)中引用的对象

2、 方法区中静态属性引用的对象

3、 方法区中常量引用的对象

4、 native方法(本地方法栈)中引用的对象

上面我们说到若没有与GC Roots相连的对象是可回收的,但是并不是就一定可以被回收,java中对象要被回收至少要经历两次标记过程:

第一次标记:若对象没有与GC Roots相连接则被第一次标记

第二次标记:这次标记需要分情况讨论

        第一种情况:若该对象的类覆盖了finalize()方法,并且该对象没有调用过finalize()方法,则虚拟机将会把该对象存入到一个叫做F-Queue队列中,等到一定的时间虚拟机将会自己创建一个低优先级的线程(Finalizer),由该线程去触发finalize()方法,若finalize()方法中将此对象与还在与GC Roots相连的对象相关联,那么该对象就不会被回收,否则该对象就会被回收

        第二种情况:finalize()方法已经被调用,或者没有覆盖finalize()方法。这种情况就不会将对象放进F-Queue队列,也不会调用finalize()方法,而是对对象进行第二次标记,回收对象

总结

通过上面的描述知道一个与GC Roots没有连接通道的对象要想不被回收就只有在finalize()方法中将该对象与GC Roots建立联系,仿佛并不是垃圾回收而是自救的一个通道,所以finalize()方法不是用于垃圾回收,而是与垃圾回收相关,除了上述作用外,还有一个作用

当该对象不进行自救时,在finalize()方法中执行该对象必须要执行的代码(因为该对象马上就要被回收),例如释放资源,这与try finally中finally的作用是一样的,并且finally可以做的更好,

转载于:https://www.cnblogs.com/zhaolei1996/p/10629628.html

你可能感兴趣的文章
hdu - 4707 - Pet
查看>>
RobotFramework下的http接口自动化Set Request Body 关键字的使用
查看>>
Kindeditor学习中的那些坑
查看>>
Servlet
查看>>
一篇价值百万的文章:我为什么在22岁辞去年薪150万的工作?
查看>>
信息安全系统设计基础期末总结
查看>>
leetcode 203 Remove Linked List Elements
查看>>
TCP/IP 笔记 1.3 IP:网际协议
查看>>
HDU 1061 Rightmost Digit
查看>>
八种简易健康减肥瘦身法
查看>>
win7旗舰版下配置IIS服务器
查看>>
web开发基础
查看>>
java——逻辑运算符与(&和&&)或(|和||)
查看>>
iPhone App开发导航条(Navigation Bar)素材PSD下载
查看>>
jQuery中的事件机制深入浅出
查看>>
当前上下文中不存在viewbag
查看>>
Laravel 上使用 phpexcel的两种方式
查看>>
Android拷贝工程不覆盖原工程的配置方法
查看>>
linux安装配置postgres及使用dblink
查看>>
ApacheBench(ab)使用详解
查看>>