Android内存泄漏浅谈

内存泄漏是指长期保持对象的引用而无法被GC回收。占用内存,造成内存泄漏。数量过多会造成内存溢出。
加载大图也可能会造成内存溢出。

GC垃圾回收 算法 1.引用计数算法(有不足之处,两个对象互相引用的时候) 2.跟搜索算法

内部类对象存在外部类的引用

new Thread(new Runnable() {
            @Override
            public void run() {
                try {
                    Thread.sleep(100000);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }).start();

解决办法 在销毁Activity的时候结束掉线程,或者将内部类定义成静态的。

Handler造成的内存泄漏

public class MainActivity extends AppCompatActivity {
    
    
    private Handler mHandler = new Handler() {
        @Override
        public void handleMessage(Message msg) {
            //...
        }
    };
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        loadData();
    }
    private void loadData(){
        //...request
        Message message = Message.obtain();
        mHandler.sendMessage(message);
    }
}
解决办法
public class MainActivity extends AppCompatActivity {
    
    
    private MyHandler mHandler = new MyHandler(this);
    private TextView mTextView ;
    //使用静态的内部类handler
    private static class MyHandler extends Handler {
    
    
        private WeakReference<Context> reference;
        public MyHandler(Context context) {
            reference = new WeakReference<>(context);
        }
        @Override
        public void handleMessage(Message msg) {
            MainActivity activity = (MainActivity) reference.get();
            if(activity != null){
                activity.mTextView.setText("");
            }
        }
    }

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mTextView = (TextView)findViewById(R.id.textview);
        loadData();
    }

    private void loadData() {
        //...request
        Message message = Message.obtain();
        mHandler.sendMessage(message);
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();
        //销毁Activity的时候移除掉发送的消息
        mHandler.removeCallbacksAndMessages(null);
    }
}

单例造成的内存泄漏

单例的Toast,在多次显示土司的时候可以立即改变显示内容。
public class ToastUtils {
    private static Toast sToast;

    public static void toast(Context context, String msg) {
        if (sToast == null) {
            sToast = Toast.makeText(context, msg, Toast.LENGTH_LONG);
        }
        sToast.setText(msg);
        sToast.show();
    }
}
修改方法讲Context.getApplicationContext()
public class ToastUtils {
    private static Toast sToast;

    public static void toast(Context context, String msg) {
        if (sToast == null) {
            sToast = Toast.makeText(context.getApplicationContext(), msg, Toast.LENGTH_LONG);
        }
        sToast.setText(msg);
        sToast.show();
    }
}

静态变量属于字节码级别的,一旦被加载就不会移除,因为加载字节码是类加载器,除非自定义一个 public class MyClassLoader extends ClassLoader{}

猜你喜欢

转载自blog.csdn.net/sinat_35541927/article/details/53268579