之所以专门写一篇关于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方法干你想要干的活相关推荐

  1. Java基础Object类的finalize方法

    1.在Object类中的源代码: protected void finalize() throws Throwable { } GC:负责调用finalize()方法. 2.finalize()方法只 ...

  2. android 光滑曲线,在Android中使用Path类的quadTo()方法实现平滑曲线

    其实,quadTo这个方法同我们平时在photoshop中所使用到的"笔迹"功能一样.说白了,就是将一条线段变成一个曲线.而这条曲线顾名思义是一条抛物线而已. API概述 publ ...

  3. android oncreate调用,Android app启动activity并调用onCreate()方法时都默默地干了什么?...

    在AndroidManifest.xml文件中的元素中有这么两句: 当写好的应用发布到手机上之后,当双击"APP"应用的图标时,系统会将这个点击时间包装成一个Intent,该Int ...

  4. Java中的finalize方法

    一.介绍 当一个对象没有引用的时候,对象的垃圾回收器会调用finalize方法. 当对象被回收时,系统自动调用该对象的finalize方法,子类可以重写该方法,做一些释放资源的操作. 什么时候被回收: ...

  5. Java基础知识强化83:System类之gc()方法(垃圾回收)以及和finalize()区别

    1. System概述: System类包含一些有用的类字段和方法.它不能被实例化. 2. gc()方法:垃圾回收器 1 public static void gc()       调用gc方法暗示着 ...

  6. ( 持续更新,目前含 200+ 工具类 ) DevUtils 是一个 Android 工具库, 主要根据不同功能模块,封装快捷使用的工具类及 API 方法调用。

    DevUtils GitHub About ( 持续更新,目前含 200+ 工具类 ) Roadmap DevUtils 是一个 Android 工具库,主要根据不同功能模块,封装快捷使用的工具类及 ...

  7. java finalize方法的使用

    <JAVA编程思想>: Java提供finalize()方法,垃圾回收器准备释放内存的时候,会先调用finalize(). (1).对象不一定会被回收. (2).垃圾回收不是析构函数. ( ...

  8. finalize java,Java中Object对象finalize方法详细解析

    简书:capo 转载请注明原创出处,谢谢! 前言: 今天我们来看看Object中一个经常被人遗忘的方法,finalize方法.老规矩,我们先看看Javadoc是怎样描述这个方法的 /** * Call ...

  9. 解决Android 编译出错 找不到android.databinding.ViewDataBinding的类文件

    报错如下: 错误: 无法访问ViewDataBinding 找不到android.databinding.ViewDataBinding的类文件 有关详细信息, 请参阅以下堆栈跟踪. com.sun. ...

最新文章

  1. 实战并发编程 - 01多线程读写同一共享变量的线程安全问题深入剖析
  2. :Windows下RabbitMQ安装及入门
  3. Java编程技巧:如何实现参数的输入输出?
  4. 浏览器工作原理(四):浏览器事件解读
  5. redis强一致性_分布式架构一定要有Redis吗?Redis的常见问题我都帮你解答了
  6. 如果波音公司破产,对美国经济的影响有多大?
  7. 拉格朗日插值法(Lagrange)
  8. mysql数据库应用的权限层级_MySQL数据库的用户权限管理
  9. all()是python内置函数吗_Python内置函数all(),python
  10. django源码阅读
  11. 引擎设计跟踪(九.2) 3DS MAX 导出插件 继续
  12. QTP9 2自带的视频教程
  13. Java运行准备JDR JRE JVM知识和环境变量的作用
  14. win7修复计算机 正常启动不了怎么办,Win7系统无法正常启动怎么办
  15. 【C++】队列优先队列详解——deque.queue.priority_queue
  16. 简单使用Search()函数
  17. 关于虚拟机中安装Ubuntu时界面显示不全的解决办法
  18. 实现Word公式和普通文本的批量互转
  19. 回溯算法--LeetCode-78 子集、LeetCode-90 子集Ⅱ
  20. Zotero使用指南06:Markdown笔记

热门文章

  1. hrbust 哈理工oj 1418 夏夜星空【带权并查集】
  2. nodejs 项目编译
  3. 利用c++STL中的map实现基本哈希族谱
  4. MySQL 使用sum求和
  5. 美术想要轻松学?一定不要错过“美术加”线上画室~
  6. java的并发和并行_JAVA中并发和并行
  7. 在IDEA中快速查找一个类的快捷键
  8. 使用静态内部类单例模式创建自定义线程池
  9. Wi-Fi感知应用逐步进入实际生活---乐鑫公司推出的ESP-WIFI-CSI智能人体感知方案
  10. citrix服务器虚拟化视频,citrix服务器虚拟化(citrix应用虚拟化)