メモリリークの最適化:静的変数によるメモリリーク

4825 ワード

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,属性アニメーションによるメモリリーク
Android 3.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();
    }
}

----------------------作者:lzy_tinyjoyソース:CSDN原文:https://blog.csdn.net/u012810020/article/details/51726699本文は博主のオリジナルの文章で、転載して博文のリンクを添付してください!