内存泄露和优化解决方案搜集

1.单例模式内存泄露:对象是静态static的 会存到程序结束使才回收.但是如果传递activity 作为 构造参数.屏幕旋转时由于activity就无法回收,导致两个activity都存在,解决方法是:传递生命周期相同的 application context 作为参数
2.非静态类声明声明静态类对象并持有非静态类对象引用:原因跟上面一样的....要么改非静态的要么持有生命周期相同的对象
3.handler 内部类:一直执行,但内部类默认持有 所在类的对象,所有此对象并不能回收. 
 解决:继承变成 静态类,并使用弱引用 并及时的remove 
  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("");
      }
    }
  }
 还要进行及时销毁回收
4.线程内部类:一直执行,但内部类默认持有 所在类的对象,所有此对象并不能回收


static boolean  flat=true;
public  void load(){
new Thread(new Runnable() {
@Override
public void run() {
while(flat){


Log.e(TAG, "run: 123456" );
SystemClock.sleep(100);
}
}
}).start();


}
通过改变 load 方法是解决了内存泄露但是线程还是在一直执行,所以要在适当的点停止.


static class MyAsyncTask extends AsyncTask<Void, Void, Void> {
    private WeakReference<Context> weakReference;
    public MyAsyncTask(Context context) {
      weakReference = new WeakReference<>(context);
    }
    @Override
    protected Void doInBackground(Void... params) {
      SystemClock.sleep(10000);
      return null;
    }
    @Override
    protected void onPostExecute(Void aVoid) {
      super.onPostExecute(aVoid);
      MainActivity activity = (MainActivity) weakReference.get();
      if (activity != null) {
        //...
      }
    }
  }  这个于handler 的解决思路是一样的


5.资源未关闭引起的内存泄露情况
比如:BroadCastReceiver、Cursor、Bitmap、IO流、自定义属性attribute
attr.recycle()回收。

6.15-23版本的输入法内存泄露解决方法 activity ondestroy 方法调用fixInputMethodManagerLeak:


public class InputMethodManagerUtils {


/**
* @param destContext 上下文对象
* 用于解决输入法内存泄露
* 参考:http://blog.csdn.net/sodino/article/details/32188809
*/
public static void fixInputMethodManagerLeak(Context destContext) {
if (destContext == null) {
return;
}


InputMethodManager imm = (InputMethodManager) destContext.getSystemService(Context.INPUT_METHOD_SERVICE);
if (imm == null) {
return;
}


String [] arr = new String[]{"mCurRootView", "mServedView", "mNextServedView"};
Field f = null;
Object obj_get = null;
for (int i = 0;i < arr.length;i ++) {
String param = arr[i];
try{
f = imm.getClass().getDeclaredField(param);
if (f.isAccessible() == false) {
f.setAccessible(true);
} // author: sodino mail:sodino@qq.com
obj_get = f.get(imm);
if (obj_get != null && obj_get instanceof View) {
View v_get = (View) obj_get;
if (v_get.getContext() == destContext) { // 被InputMethodManager持有引用的context是想要目标销毁的
f.set(imm, null); // 置空,破坏掉path to gc节点
} else {
// 不是想要目标销毁的,即为又进了另一层界面了,不要处理,避免影响原逻辑,也就不用继续for循环了
break;
}
}
}catch(Throwable t){
t.printStackTrace();
}
}
}
}
ps:http://blog.csdn.net/sodino/article/details/32188809


7.无限循环动画
没有在onDestroy中停止动画,否则Activity就会变成泄露对象。
比如:轮播图效果。


8.bitmap 优化: 三级缓存:内存lru ,文件,网络. 压缩优化:终极优化,说是什么微信压缩 libjpeg 压缩引擎:在https://github.com/chenrongfa/bitmapUtil
参考于:http://www.jianshu.com/p/e9e1db845c21
9.ui 优化: 使用hierarchy view 进行布局优化,或者说简单化.过度绘制:删除不必要背景,裁剪看不见的视图.
参考于:https://segmentfault.com/a/1190000004547751
10.安装包优化:lint工具优化,混淆app 但是大部分由activiy 和view 组成 发现作用还是没多大...感觉还是关键类混淆.. 总结http://blog.csdn.net/chenliguan/article/details/54176626

7zzip 资源压缩工具:https://github.com/chenrongfa/7zzip 微信的 https://github.com/shwenzhang/AndResGuard

11.minifyEnabled true开启混淆 shrinkResources  true 删除无用的资源 上个起作用时才能起作用 (反射获取的资源会删除)  

12.  如果没有对多个国际支持的要求话,下面就够了  defaultConfig {

        resConfigs "en","fr","zh"

}

apk 的国际化资源会只有en fr  zh

13.基本类型常量和String 类常量尽可能用static final 因为在常量池中,不用类初始化,读取快.其他引用类型的常量,应该慎用,因为占用空间会很大,也可能造成内存泄露........还有前两者存储不大,

14.内部类的属性应该直接读取,不应该getter和setter读取

15.图片首选webp, 背景可以.9 或者简单的用shape画

16.使用TextView +drawablexxxx来提高性能和减少子view的数量. TextView+imageView 控制图片大小和添加动画都是比较方便灵活

17.ViewStubCompat 来实现延迟加载,不要把对象创建和视图加载的什么都放到类的初始化,这样集中也会造成内存抖动和反应慢的问题(再小也是肉)不能和merge一起使用  报错 <merge /> can be used only with a valid ViewGroup root and attachToRoot=true

18.如果多个布局xml文件有些地方使用相同的布局xml代码 ,可以像代码一样抽象封装成一个xml 使用include 使xml代码减少 ....并且如果 这个封装布局xml文件根节点的View 于include 所在的根节点相同可以用merge替换

19.内存管理: http://blog.csdn.net/guolin_blog/article/details/42238627 onTrimMemory()应该在application 中重写不然不会调用

20. Webview 内存泄露: http://www.jianshu.com/p/4ee7c0870dec

ps:待搜集

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值