Android内存优化4 了解java GC 垃圾回收机制2 GC执行finalize的过程
1. finalize的作用
- finalize()是Object的protected方法,子类可以覆盖该方法以实现资源清理工作,GC在回收对象之前调用该方法。
- finalize()与C++中的析构函数不是对应的。C++中的析构函数调用的时机是确定的(对象离开作用域或delete掉),但Java中的finalize的调用具有不确定性
- 不建议用finalize方法完成“非内存资源”的清理工作,但建议用于:① 清理本地对象(通过JNI创建的对象);② 作为确保某些非内存资源(如Socket、文件等)释放的一个补充:在finalize方法中显式调用其他资源释放方法。其原因可见下文[finalize的问题]
2. finalize的问题
- 一些与finalize相关的方法,由于一些致命的缺陷,已经被废弃了,如System.runFinalizersOnExit()方法、Runtime.runFinalizersOnExit()方法
- System.gc()与System.runFinalization()方法增加了finalize方法执行的机会,但不可盲目依赖它们
- Java语言规范并不保证finalize方法会被及时地执行、而且根本不会保证它们会被执行
- finalize方法可能会带来性能问题。因为JVM通常在单独的低优先级线程中完成finalize的执行
- 对象再生问题:finalize方法中,可将待回收对象赋值给GC Roots可达的对象引用,从而达到对象再生的目的
- finalize方法至多由GC执行一次(用户当然可以手动调用对象的finalize方法,但并不影响GC对finalize的行为)
3. finalize的执行过程(生命周期)
- unfinalized: 新建对象会先进入此状态,GC并未准备执行其finalize方法,因为该对象是可达的
- finalizable: 表示GC可对该对象执行finalize方法,GC已检测到该对象不可达。正如前面所述,GC通过F-Queue队列和一专用线程完成finalize的执行
- finalized: 表示GC已经对该对象执行过finalize方法
- reachable: 表示GC Roots引用可达
- finalizer-reachable(f-reachable):表示不是reachable,但可通过某个finalizable对象可达
- unreachable:对象不可通过上面两种途径可达
- 新建对象首先处于[reachable, unfinalized]状态(A)
- 随着程序的运行,一些引用关系会消失,导致状态变迁,从reachable状态变迁到f-reachable(B, C, D)或unreachable(E, F)状态
- 若JVM检测到处于unfinalized状态的对象变成f-reachable或unreachable,JVM会将其标记为finalizable状态(G,H)。若对象原处于[unreachable,
unfinalized]状态,则同时将其标记为f-reachable(H)。 - 在某个时刻,JVM取出某个finalizable对象,将其标记为finalized并在某个线程中执行其finalize方法。由于是在活动线程中引用了该对象,该对象将变迁到(reachable,
finalized)状态(K或J)。该动作将影响某些其他对象从f-reachable状态重新回到reachable状态(L, M, N) - 处于finalizable状态的对象不能同时是unreahable的,由第4点可知,将对象finalizable对象标记为finalized时会由某个线程执行该对象的finalize方法,致使其变成reachable。这也是图中只有八个状态点的原因
- 程序员手动调用finalize方法并不会影响到上述内部标记的变化,因此JVM只会至多调用finalize一次,即使该对象“复活”也是如此。程序员手动调用多少次不影响JVM的行为
- 若JVM检测到finalized状态的对象变成unreachable,回收其内存(I)
- 若对象并未覆盖finalize方法,JVM会进行优化,直接回收对象(O)
- 注:System.runFinalizersOnExit()等方法可以使对象即使处于reachable状态,JVM仍对其执行finalize方法
4. 一些代码示例
(1) 对象复活
- publicclass
publicstaticnull
publicstaticvoidthrows
new
null);
- ifnull
- else
null
);
- ifnull
else
- protectedvoidthrows
superthis
}
(2)覆盖finalize方法以确保资源释放
作为一个补充操作,以防用户忘记“关闭“资源,JDK中FileInputStream、FileOutputStream、Connection类均用了此”技术“,下面代码摘自FileInputStream类
- /**
- * Ensures that the <code>close</code> method of this file input stream is
- * called when there are no more references to it.
- *
- * @exception IOException if an I/O error occurs.
- * @see java.io.FileInputStream#close()
- */
protectedvoidthrows
ifnull* will ensure that finalizer is only called when
- * safe to do so. All references using the fd have
- * become unreachable. We can call close()
- */
}
参考:
12.6 Finalization of Class Instances https://notendur.hi.is//~snorri/SDK-docs/lang/lang083.htm深入理解java的finalize http://zhang-xzhi-xjtu.iteye.com/blog/484934The Finalizable Object http://www.artima.com/interfacedesign/Finalizable.htm
Android内存优化4 了解java GC 垃圾回收机制2 GC执行finalize的过程的更多相关文章
- 浅析JAVA的垃圾回收机制(GC)
1.什么是垃圾回收? 垃圾回收(Garbage Collection)是Java虚拟机(JVM)垃圾回收器提供的一种用于在空闲时间不定时回收无任何对象引用的对象占据的内存空间的一种机制. 注意:垃圾回 ...
- JAVA的垃圾回收机制(GC)
1.什么是垃圾回收? 垃圾回收(Garbage Collection)是Java虚拟机(JVM)垃圾回收器提供的一种用于在空闲时间不定时回收无任何对象引用的对象占据的内存空间的一种机制. 2.什么时候 ...
- java面试题之----JVM架构和GC垃圾回收机制详解
JVM架构和GC垃圾回收机制详解 jvm,jre,jdk三者之间的关系 JRE (Java Run Environment):JRE包含了java底层的类库,该类库是由c/c++编写实现的 JDK ( ...
- JVM和GC垃圾回收机制和内存分配
JVM运行期间 线程共享 线程私有 线程共享: 方法区 堆方法区:存放可以共享数据,静态常量,类的共有方法属性字段等,可以共享的存在方法区. 堆:存放class对象 . 线程私有:本地方法栈 虚拟机栈 ...
- 面试官,不要再问我“Java GC垃圾回收机制”了
Java GC垃圾回收几乎是面试必问的JVM问题之一,本篇文章带领大家了解Java GC的底层原理,图文并茂,突破学习及面试瓶颈. 楔子-JVM内存结构补充 在上篇<JVM之内存结构详解> ...
- 乐字节Java|GC垃圾回收机制、package和import
本文接上一篇:乐字节Java|this关键字.static关键字.block块.本文是接着讲述JavaGC垃圾回收机制.package 和 import语句. 一.GC垃圾回收机制 GC全名:Garb ...
- Java垃圾回收机制(GC策略)
Java垃圾回收机制(GC策略) 核心:1,哪些是垃圾?[怎么确定这个是垃圾]:2,如何回收垃圾?[怎么更好收垃圾]. Java语言相对于C++等语言有一个自动垃圾回收机制,只用管使用[实例化对象], ...
- 记录Java的垃圾回收机制和几种引用
一.Java的垃圾回收机制 Java的垃圾回收机制(java garbage collection)是Java虚拟机提供的能力,用于在空闲时间以不定时的方式动态回收无任何引用的对象占据的堆内存空间. ...
- 了解java中垃圾回收机制
Java的垃圾回收机制是Java环境自带有的,它不像c语言的malloc申请空间后需要Free()函数来释放,而Java中的代码块中所申请的空间可在程序执行完成后自动释放,但是是有局限性的,代码块所占 ...
随机推荐
- An In-Depth Look at the HBase Architecture
https://www.mapr.com/blog/in-depth-look-hbase-architecture An In-Depth Look at the HBase Architectur ...
- HIbernate学习笔记5 之 查询
一.HQL查询 * 按条件查询,条件中写的是属性名,之后在query对象为添加赋值,如: String hql = " from User where uid=?"; Sessio ...
- Guava Cache 使用笔记
https://www.cnblogs.com/parryyang/p/5777019.html https://www.cnblogs.com/shoren/p/guava_cache.html J ...
- Python安装scikit-learn包
我先是按照网上说的下载了个setuptools,然后直接用这个工具去安装,可是安装scikit-learn包的时候确老是有错误,也不知道错误是啥,所以就不用setuptools来安装了. 我直接下载了 ...
- yii2-admin扩展自定义目录
yii2-admin文件如下.仓库地址: https://github.com/mdmsoft/yii2-admin/tree/master 复制yii2-admin文件至自定义目录 比如我就复制到 ...
- AC日记——[POI2008]BLO-Blockade 洛谷 [POI2008]BLO-Blockade
[POI2008]BLO-Blockade 思路: tarjan: 代码: #include <bits/stdc++.h> using namespace std; #define ma ...
- 【转载】Web Service 的工作原理
http://www.cnblogs.com/Jessy/p/3528341.html Web Service基本概念 Web Service也叫XML Web Service WebService是 ...
- jquery扩展插件,让demo元素也可以resize
(function($, h, c) { var a = $([]), e = $.resize = $.extend($.resize, {}), i, k = "setTimeout&q ...
- 【ASP.NET MVC】HTML5+MVC上传文件显示进度
head> <title>Index</title> <style type="text/css"> #statusBorder { po ...
- Java-多线程编程(一)
创建多线程 [Thread class]1.继承Thread类,重写run() [Runnable接口]2.实现Runnable接口,重写run() [*Callable接口]3.实现Callable ...