之所以专门写了一篇文章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;
}
} @Override
protected 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. 命令行下使用javah命令生成.h文件,出现“错误: 无法访问android.app.Activity 找不到android.app.Activity的类文件”的解决方法

    在学习NDK中,当我在项目的bin/classes目录下使用javah命令生成头文件时,出现了“错误: 无法访问android.app.Activity 找不到android.app.Activity ...

  2. 【Android笔记】Thread类中关于join()方法的源码分析

    1.join()方法的作用: 例如有一个线程对象为Thread1,在main()方法中调用Thread1.join()方法可使得当前线程(即主线程)阻塞,而执行Thread1线程. 2.源码分析(以上 ...

  3. 【Android开发经验】使用反射,得到的类的字段、方法、并实现了简单的调用

    本文后推出Android的ICO框架做准备,所以,假设你想要一个最近的一项研究Android的ICO学生框架.你可以稍微看一下. 首先,简介一下Java里面的反射. JAVA反射机制是在执行状态中,对 ...

  4. Android 通过 Intent 传递类对象或list对象

    (转:http://www.cnblogs.com/shaocm/archive/2013/01/08/2851248.html) Android中Intent传递类对象提供了两种方式一种是 通过实现 ...

  5. android SQLite使用SQLiteOpenHelper类对数据库进行操作

    android SQLite使用SQLiteOpenHelper类对数据库进行操作 原文: http://byandby.iteye.com/blog/835580

  6. 【Java基础之Object类(一)】Java中Object类中的所有方法(toString、equals、hashCode、clone、finalize、wait和notify等)详解(转载)

    java中的hashcode.equals和toString方法都是基类Object的方法. 首先说说toString方法,简单的总结了下API说明就是:返回该对象的字符串表示,信息应该是简明但易于读 ...

  7. Android反射出一个类中的其他类对象并调用其对应方法

    MainActivity如下: package cn.testreflect; import java.lang.reflect.Field; import java.lang.reflect.Met ...

  8. Android中利用画图类和线程画出闪烁的心形

                                                        本文讲解主要涉及的知识点: 1.线程控制 2.画图类 3.心形函数 大家先看图片: <ig ...

  9. Android 通过 Intent 传递类对象

    Android中Intent传递类对象提供了两种方式一种是 通过实现Serializable接口传递对象,一种是通过实现Parcelable接口传递对象. 要求被传递的对象必须实现上述2种接口中的一种 ...

随机推荐

  1. Servlet(七)生成验证码

    1.ImageCode.java package com.hunhun.utils; import java.awt.Color; import java.awt.Font; import java. ...

  2. UVA 11237 - Halloween treats(鸽笼原理)

    11237 - Halloween treats option=com_onlinejudge&Itemid=8&page=show_problem&category=516& ...

  3. tolua 有些功能可以用(经过测试)

    tolua 提供几个 C++ 与 Lua 进行数据交换的工具函数. ~~ tolua.type 返回一个 C++ 对象的类型描写叙述字符串. local node = display.newNode( ...

  4. PhantomJS是一个基于WebKit的服务器端JavaScript API

    PhantomJS是一个基于WebKit的服务器端JavaScript API,它基于 BSD开源协议发布.PhantomJS无需浏览器的支持即可实现对Web的支持,且原生支持各种Web标准,如DOM ...

  5. 秒杀多线程第二篇 多线程第一次亲热接触 CreateThread与_beginthreadex本质差别

    本文将带领你与多线程作第一次亲热接触,并深入分析CreateThread与_beginthreadex的本质差别,相信阅读本文后你能轻松的使用多线程并能流畅准确的回答CreateThread与_beg ...

  6. Java中字符串中子串的查找共有四种方法(indexof())

    Java中字符串中子串的查找共有四种方法(indexof()) Java中字符串中子串的查找共有四种方法,如下:1.int indexOf(String str) :返回第一次出现的指定子字符串在此字 ...

  7. Mac下配置Cocos2d-x3.1环境

    一.前期准备 1.ADT:百度下就OK 2.NDK:百度下就OK 3.ANT: http://124.254.47.39/download/55152992/78533365/4/zip/57/132 ...

  8. Spring框架简单介绍

    原文地址:  http://my.oschina.net/myriads/blog/37922 1.使用框架的意义与Spring的主要内容 随着软件结构的日益庞大,软件模块化趋势出现,软件开发也须要多 ...

  9. Windows phone 8 学习笔记(3) 通信

    原文:Windows phone 8 学习笔记(3) 通信 Windows phone 8 可利用的数据通信方式比较广泛,在硬件支持的前提下,我们可以利用WiFi.蓝牙.临近感应等多种方式.数据交互一 ...

  10. 集合中Set_List必须覆盖 hashCode()与 equals()

    集合中Set_List必须覆盖 hashCode()与 equals() @Override public int hashCode() { System.out.println("==== ...