Android开发经验—不要指望类的finalize方法干你想要干的活
之所以专门写一篇关于finalize方法的博客,是因为被这个方法坑过,在写一个读取jni数据类的时候,我在类的finalize方法中调用了关闭文件和释放内存的方法,结果导致在频繁调用这个类的时候在JNI里面报异常,类本来就是单例的,按理分析不应该存在这样的情况,到最后分析出来就是因为在该类的finalize方法中调用了关闭文件的方法,导致下次进入再次打开文件时,被系统调用finalize方法给关闭掉了,出现异常的代码如下。
public class TraceHandle{static{try{System.loadLibrary("TraceHandle");}catch (UnsatisfiedLinkError ule){Log.e("JNI", "WARNING: Could not load TraceHandle.so");}}private TraceHandle( String filePath ){mFilePath = filePath;open( filePath );}/*** 实例化TraceHandle* * */public static TraceHandle create( String filePath ){if (null == mTraceHandle){mTraceHandle = new TraceHandle( filePath);}mTraceHandle.mInitCount++;return mTraceHandle;}/*** 退出时销毁TraceHandle* * @return null.*/public TraceHandle destory( ){mInitCount--;if (mInitCount == 0 && mTraceHandle != null){mTraceHandle.close();mTraceHandle = null;}return null;}private void celan(){if (mTraceHandle != null){mTraceHandle.close();mTraceHandle = null;}}@Overrideprotected void finalize() throws Throwable{super.finalize();//这是被系统调用的方法,系统会根据系统环境来调用,对于程序来说它的调用实际不可预见celan();}// 1、打开文件private native int open(String tracePath );// 2、搜索指定汉字private native int[] search(byte[] wordArray);// 3、必须关闭文件private native boolean close();private int mInitCount = 0;private String mFilePath = null;private static TraceHandle mTraceHandle = null;
}
经过查阅资料和阅读《JAVA核心技术》里面相关的章节后,问题终于搞定。在《JAVA核心技术》一书中是这样描述finalize方法的:
“可以为任何一个类添加finalize方法。finalize方法将在垃圾回收器清除对象之前调用。在实际应用中,不要依赖于使用finalize方法回收任何短缺的资源,这是因为很难知道这个方法什么时候才能够调用。
如果某个资源需要在使用完毕立刻被关闭,那么就需要由人工来管理。可以应用一个类似dispose或close的放来完成相应的清理操作。特别需要说明,如果一个类使用了这样的方法,当对象不再被使用时一定要调用它。”
修改后的代码如下,去掉了finalize方法:
public class TraceHandle{static{try{System.loadLibrary("TraceHandle");}catch (UnsatisfiedLinkError ule){Log.e("JNI", "WARNING: Could not load TraceHandle.so");}}private TraceHandle( String filePath ){mFilePath = filePath;open( filePath );}/*** 实例化TraceHandle* * */public static TraceHandle create( String filePath ){if (null == mTraceHandle){mTraceHandle = new TraceHandle( filePath);}mTraceHandle.mInitCount++;return mTraceHandle;}/*** 退出时销毁TraceHandle* * @return null.*/public TraceHandle destory( ){mInitCount--;if (mInitCount == 0 && mTraceHandle != null){mTraceHandle.close();mTraceHandle = null;}return null;}private void celan(){if (mTraceHandle != null){mTraceHandle.close();mTraceHandle = null;}}// 1、打开文件private native int open(String tracePath );// 2、搜索指定汉字private native int[] search(byte[] wordArray);// 3、必须关闭文件private native boolean close();private int mInitCount = 0;private String mFilePath = null;private static TraceHandle mTraceHandle = null;
}
由于java有自己的垃圾回收机制,所以在写代码的时候千万不能依赖于它的一些方法来回收资源(比如finalize,gc),因为这些方法的调用时机都是不可预知的。
参考资料:
1、Why not to use finalize() method in java
2、When is the finalize() method called in Java?
Android开发经验—不要指望类的finalize方法干你想要干的活相关推荐
- Java基础Object类的finalize方法
1.在Object类中的源代码: protected void finalize() throws Throwable { } GC:负责调用finalize()方法. 2.finalize()方法只 ...
- android 光滑曲线,在Android中使用Path类的quadTo()方法实现平滑曲线
其实,quadTo这个方法同我们平时在photoshop中所使用到的"笔迹"功能一样.说白了,就是将一条线段变成一个曲线.而这条曲线顾名思义是一条抛物线而已. API概述 publ ...
- android oncreate调用,Android app启动activity并调用onCreate()方法时都默默地干了什么?...
在AndroidManifest.xml文件中的元素中有这么两句: 当写好的应用发布到手机上之后,当双击"APP"应用的图标时,系统会将这个点击时间包装成一个Intent,该Int ...
- Java中的finalize方法
一.介绍 当一个对象没有引用的时候,对象的垃圾回收器会调用finalize方法. 当对象被回收时,系统自动调用该对象的finalize方法,子类可以重写该方法,做一些释放资源的操作. 什么时候被回收: ...
- Java基础知识强化83:System类之gc()方法(垃圾回收)以及和finalize()区别
1. System概述: System类包含一些有用的类字段和方法.它不能被实例化. 2. gc()方法:垃圾回收器 1 public static void gc() 调用gc方法暗示着 ...
- ( 持续更新,目前含 200+ 工具类 ) DevUtils 是一个 Android 工具库, 主要根据不同功能模块,封装快捷使用的工具类及 API 方法调用。
DevUtils GitHub About ( 持续更新,目前含 200+ 工具类 ) Roadmap DevUtils 是一个 Android 工具库,主要根据不同功能模块,封装快捷使用的工具类及 ...
- java finalize方法的使用
<JAVA编程思想>: Java提供finalize()方法,垃圾回收器准备释放内存的时候,会先调用finalize(). (1).对象不一定会被回收. (2).垃圾回收不是析构函数. ( ...
- finalize java,Java中Object对象finalize方法详细解析
简书:capo 转载请注明原创出处,谢谢! 前言: 今天我们来看看Object中一个经常被人遗忘的方法,finalize方法.老规矩,我们先看看Javadoc是怎样描述这个方法的 /** * Call ...
- 解决Android 编译出错 找不到android.databinding.ViewDataBinding的类文件
报错如下: 错误: 无法访问ViewDataBinding 找不到android.databinding.ViewDataBinding的类文件 有关详细信息, 请参阅以下堆栈跟踪. com.sun. ...
最新文章
- 实战并发编程 - 01多线程读写同一共享变量的线程安全问题深入剖析
- :Windows下RabbitMQ安装及入门
- Java编程技巧:如何实现参数的输入输出?
- 浏览器工作原理(四):浏览器事件解读
- redis强一致性_分布式架构一定要有Redis吗?Redis的常见问题我都帮你解答了
- 如果波音公司破产,对美国经济的影响有多大?
- 拉格朗日插值法(Lagrange)
- mysql数据库应用的权限层级_MySQL数据库的用户权限管理
- all()是python内置函数吗_Python内置函数all(),python
- django源码阅读
- 引擎设计跟踪(九.2) 3DS MAX 导出插件 继续
- QTP9 2自带的视频教程
- Java运行准备JDR JRE JVM知识和环境变量的作用
- win7修复计算机 正常启动不了怎么办,Win7系统无法正常启动怎么办
- 【C++】队列优先队列详解——deque.queue.priority_queue
- 简单使用Search()函数
- 关于虚拟机中安装Ubuntu时界面显示不全的解决办法
- 实现Word公式和普通文本的批量互转
- 回溯算法--LeetCode-78 子集、LeetCode-90 子集Ⅱ
- Zotero使用指南06:Markdown笔记