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();
    
        }
    
    }
  • 相关阅读:
    php date 时间差
    array_merge 和 + 号的的区别
    apache 添加https后导致http无法访问
    php 获取url
    TP5 事务处理
    LeetCode 每日一题 (盛最多水的容器)
    LeetCode 每日一题 (字符串转换整数 (atoi))
    LeetCode 每日一题(5. 最长回文子串)
    LeetCode 每日一题 (3 无重复字符的最长子串)
    LeetCode 每日一题 (两数相加)
  • 原文地址:https://www.cnblogs.com/leeego-123/p/12187677.html
Copyright © 2011-2022 走看看