zoukankan      html  css  js  c++  java
  • 常见的内存泄漏原因及解决方法

    1、要不怎么说static关键字要慎用呢?来看看下面这段代码,Context对象为静态的,那么Activity就无法正常销毁,会常驻内存。

    public class MainActivity extends Activity{
    
        public static Context mContext;
    
        @Override
    
        protected void onCreate(Bundle savedInstanceState) {
    
            super.onCreate(savedInstanceState);
    
            setContentView(R.layout.activity_main);
    
            mContext = this;
    
        }
    
    }

    解决办法:1使用Application的Context。 2慎用statistic关键字
    2、单例模式导致内存的泄漏

    静态变量导致的内存泄漏太过明显,而单例模式带来的内存的泄漏容易被忽略。

    public class MyDBHelper extends SQLiteOpenHelper {
    
        public static final String DB_NAME = "mydb.db";
    
        public static final int DATABASE_VERSION = 1;
    
        public static MyDBHelper instance = null;
    
        private static final Object mMutex = new Object();
    
     
    
        private static final String DB_TABLE_STUDENT = "students";
    
        private static final String DB_TABLE_TEACHER = "teacher";
    
     
    
        private String studentTableSql = "CREATE TABLE IF NOT EXISTS students (id integer primary key autoincrement,name varchar(10),age varchar(10),sex varcher(10))";
    
        private String teacherTableSql = "CREATE TABLE IF NOT EXISTS teacher (id integer primary key autoincrement,name varchar(10),age varchar(10))";
    
     
    
        /**
    
         * 功能描述:单例模式创建MyDBHelper实例
    
         *
    
         * @param context
    
         * @return
    
         */
    
        public static MyDBHelper getInstance(Context context) {
    
            if (instance == null) {
    
                synchronized (mMutex) {
    
                    if (instance == null) {
    
                        instance = new MyDBHelper(context);
    
                    }
    
                }
    
            }
    
            return instance;
    
        }
    
     
    
     
    
        public MyDBHelper(Context context) {
    
            super(context, DB_NAME, null, DATABASE_VERSION);
    
        }
    
     
    
        /**
    
         * 方法描述: 构造方法
    
         *
    
         * @param context 上下文
    
         * @param name    数据库名称
    
         * @param factory
    
         * @param version
    
         */
    
        public MyDBHelper(Context context, String name, SQLiteDatabase.CursorFactory factory, int version) {
    
            super(context, name, factory, version);
    
        }
    
     
    
        /**
    
         * 方法描述:创建数据库
    
         *
    
         * @param db
    
         */
    
        @Override
    
        public void onCreate(SQLiteDatabase db) {
    
            db.execSQL(studentTableSql);
    
            db.execSQL(teacherTableSql);
    
        }
    
     
    
        @Override
    
        public void onUpgrade(SQLiteDatabase db, int oldVersion, int newVersion) {
    
     
    
        }
    
    }

    我们在使用的时候经常会犯一些错误:

    /**
    
     * Created by lizhenya.
    
     */
    
    public class HomeActivity extends Activity {
    
        Button btn_home;
    
        @Override
    
        protected void onCreate(Bundle savedInstanceState) {
    
            super.onCreate(savedInstanceState);
    
            requestWindowFeature(Window.FEATURE_NO_TITLE);
    
            setContentView(R.layout.layout_home);
    
            MyDBHelper().getInstances(this);
    
        }
    
    }


        单例模式的特点就是它的生命周期和Application一样,那么如果某个Activity实例被一个单例所持有,也就是说在单例里面引用了它,那么就会造成Activity对象无法正常回收释放。所以我们尽量的使用Application的全局Context。
    3,属性动画导致的内存泄漏

        从Android3.0开始,Google提供了属性动画,属性动画中有一类无限循环的动画,如果在Activity中播放此类动画并且在onDestroy()方法中没有停止该动画,那么动画会一直循环下去,尽管在界面上已经无法看不到动画了,但这个时候Activity的View会被动画持有,而View又持有Activity,最终Activity无法释放。下面的动画是无限循环的,会泄露当前的Activity。

    /**
    
     * Created by lizhenya.
    
     */
    
    public class HomeActivity extends Activity {
    
        Button btn_home;
    
     
    
        @Override
    
        protected void onCreate(Bundle savedInstanceState) {
    
            super.onCreate(savedInstanceState);
    
            requestWindowFeature(Window.FEATURE_NO_TITLE);
    
            setContentView(R.layout.layout_home);
    
            btn_home = (Button) findViewById(R.id.btn_home);
    
            ObjectAnimator animator = ObjectAnimator.ofFloat(btn_home, "ratation", 0, 360).setDuration(2000);
    
            animator.setRepeatCount(ValueAnimator.INFINITE);
    
            animator.start();
    
        }
    
    }

    解决方案:
        在当前Activity的onDestroy()方法中取消动画:animator.cancel()。

    /**
    
     * Created by lizhenya.
    
     */
    
    public class HomeActivity extends Activity {
    
        private Button btn_home;
    
        private ObjectAnimator animator;
    
     
    
        @Override
    
        protected void onCreate(Bundle savedInstanceState) {
    
            super.onCreate(savedInstanceState);
    
            requestWindowFeature(Window.FEATURE_NO_TITLE);
    
            setContentView(R.layout.layout_home);
    
            btn_home = (Button) findViewById(R.id.btn_home);
    
     
    
            animator = ObjectAnimator.ofFloat(btn_home, "ratation", 0, 360).setDuration(2000);
    
            animator.setRepeatCount(ValueAnimator.INFINITE);
    
            animator.start();
    
        }
    
     
    
        @Override
    
        protected void onDestroy() {
    
            super.onDestroy();
    
            animator.cancel();
    
        }
    
    }
  • 相关阅读:
    数据库表结构变动发邮件脚本
    .net程序打包部署
    无法登陆GitHub解决方法
    netbeans 打包生成 jar
    第一次值班
    RHEL6 纯命令行文本界面下安装桌面
    C语言中格式化输出,四舍五入类型问题
    I'm up to my ears
    How to boot ubuntu in text mode instead of graphical(X) mode
    the IP routing table under linux@school
  • 原文地址:https://www.cnblogs.com/leeego-123/p/12187677.html
Copyright © 2011-2022 走看看