zoukankan      html  css  js  c++  java
  • 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;
            }
        }
    
        @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?


  • 相关阅读:
    最全的静态网站生成器(开源项目)
    移动互联网流量变现模式调研问卷
    公众平台商户接入(微信支付)功能申请教程
    微信支付全面开放
    百度天气预报接口
    微信公众平台开发(83) 生成带参数二维码
    微信支付接口申请指南
    微信自媒体账号涉违规大规模被封
    php大文件上传解决方案支持分片断点上传
    html5大文件上传解决方案(500M以上)
  • 原文地址:https://www.cnblogs.com/bhlsheji/p/5039072.html
Copyright © 2011-2022 走看看