mg4377娱乐娱城官网_mg4377娱乐手机版_www.mg4377.com

内部存款和储蓄器走漏优化,常见内部存款和储

时间:2019-09-08 07:49来源:mg4377娱乐手机版
参照他事他说加以考察:Android应用内部存款和储蓄器败露分析、改正经验总括使用新版AndroidStudio检查评定内部存款和储蓄器走漏和特性搞定安卓CPU使用率过高难题AndroidCPU使用过大的难

参照他事他说加以考察:Android应用内部存款和储蓄器败露分析、改正经验总括使用新版Android Studio检查评定内部存款和储蓄器走漏和特性搞定安卓CPU使用率过高难题Android CPU使用过大的难点消除以及变成的原委AndroidStudio CPU Monitor使用介绍Skipped 60 frames! The application may be doing too much work on its main thread

mg4377娱乐手机版,内部存款和储蓄器走漏优化,常见内部存款和储蓄器走漏及优化方案。前言:通过方今对有些个利用的内存败露检查评定和创新,效果显著:完全退出应用时,手动触发GC,从原本据有内部存款和储蓄器100多M降到低于20M;手动触发GC后,通过adb shell dumpsys meminfo packagename -d查看Activity和View的数码也趋近于0了(未有大功告成归零是因为SDK中留存内部存款和储蓄器走漏,要求中间层去管理);发掘了三个SDK中的内部存款和储蓄器泄露(Android InputMethodManager 导致的内部存款和储蓄器走漏及实施方案);发掘两个联发科Webview的内部存款和储蓄器走漏(org.chromium.android_webview.AwPasswordHandler.java中private static AwPasswordHandler sInstance = null导致的内部存款和储蓄器泄露)。

单例持有对象 变成泄漏

单例的静态性子使得单例的生命周期和利用的生命周期一样长,假诺八个目的已经无需动用了,而单例对象还具备该对象的引用,那么那么些目的将无法被平常回收,那就导致了内部存款和储蓄器泄漏。

public class AppManager {
    private static AppManager instance;
    private Context context;
    private AppManager(Context context) {
        this.context = context;
    }
    public static AppManager getInstance(Context context) {
        if (instance != null) {
            instance = new AppManager(context);
        }
        return instance;
    }
}

这里传出的那是三个一般性的单例情势,当创造那些单例的时候,由于供给传入二个Context,所以那么些Context的生命周期的尺寸至关心爱慕要:
传播的是Application的Context:那将从未任何难题,因为单例的生命周期和Application的平等长
传扬的是Activity的Context:当Activity被销毁的时候,而单例还装有该指标,不能够平日被系统回收,导致败露

若果多个失效的指标(没有需要在接纳的靶子),依旧被其余对象具有使用,产生该目的不只怕被系统回收。以致该对象在堆中对据有的内部存款和储蓄器单元无法被放走变成内部存储器空间浪费,这种状态就是内部存储器泄漏。

内存走漏能够挑动过多的主题素材,常见的内部存款和储蓄器败露导致难题如下:

从结果来看作者剖判和订正内部存款和储蓄器走漏的不二秘技是对的,这一个进度并不复杂,所以能够梳理计算出来作为享受。

Handler 形成内部存款和储蓄器走漏

如handler.postDeslayed 可能还会有另外未形成的职责在实行,handler会一向并存,满含它的 MainActivity 就跟着活,而以此时候MainActivity 被销毁了,导致不可能即时被gc回收,发生内部存款和储蓄器败露

public class MainActivity extends Activity {
  Handler handler;
  @Override
  protected void onCreate(Bundle savedInstanceState) {
    super.onCreate(savedInstanceState);
    handler = new Handler() {
      @Override
      public void handleMessage(Message msg) {
      }
  }
}

对照非静态内部类,最佳使用静态内部类 Handler,静态内部类不借助于所属类,他们具有不一致的生命周期,并且动用弱引用WeakReference,垃圾回收器在回收的时候,是会忽略掉弱引用的,所以饱含它的 Activity 会被符合规律清理掉,并且在销毁的时候清空Handler里面包车型大巴音信

    private Handler mHandler;
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        mHandler = new MyHandler(this);
        start();
    }

    private void start() {
        Message msg = Message.obtain();
        msg.what = 1;
        mHandler.sendMessage(msg);
    }

    private static class MyHandler extends Handler {
        private WeakReference<MainActivity> activityWeakReference;

        public MyHandler(MainActivity activity) {
            activityWeakReference = new WeakReference<>(activity);
        }

        @Override
        public void handleMessage(Message msg) {
            MainActivity activity = activityWeakReference.get();
            if (activity != null) {
                if (msg.what == 1) { 
                   // 做相应逻辑
                }
            }
        }
    }
   @Override
   protected void onDestroy() {
       super.onDestroy();
       mHandler.removeCallbacksAndMessages(null);
   }

在Android开垦中,一些倒霉的编制程序习贯会导致大家的支出的app存在内存走漏的图景。上边介绍部分在Android开拓中普及的内部存款和储蓄器败露场景及优化方案。

  • 动用卡顿,响应速度慢(内部存款和储蓄器占用高时JVM虚构机缘频繁触发GC);

  • 利用被从后台进度干为空进度(上边系统内部存储器原理有介绍,也正是超过了阈值);

  • 动用莫名的夭亡(上边运用内部存款和储蓄器原理有介绍,也正是赶上了阈值OOM);

法则对于品质难点,深入分析和改进有不能缺少遵从以下标准:

Activity产生泄漏

Activity 泄漏平常是内部存款和储蓄器泄漏的一种。假如持有一个未利用的 Activity 的引用,其实也就持有了 Activity 的布局,自然也就带有了独具的 View。持有静态援用供给极度注意。Activity 和 Fragment 都有和煦的生命周期。一旦大家全部了静态援用,Activity 和 Fragment 就不会被垃圾回收器清理掉了。

单例导致内部存款和储蓄器败露

单例情势在Android开采中会常常使用,不过倘若使用不当就能够招致内部存款和储蓄器走漏。因为单例的静态性格使得它的生命周期同使用的生命周期同样长,倘使一个目的已经远非用处了,可是单例还装有它的援用,那么在漫天应用程序的生命周期它都不能够健康被回收,从而导致内存败露。
单例形式在Android开辟中会平常使用,但是只要使用不当就能够导致内部存款和储蓄器走漏。因为单例的静态本性使得它的生命周期同使用的生命周期同样长,假使三个对象已经远非用处了,但是单例还会有所它的援用,那么在漫天应用程序的生命周期它都不能够平日被回收,进而导致内存走漏。

public class AppSettings {
     private static AppSettings sInstance;
     private Context mContext;

     private AppSettings(Context context) {
          this.mContext = context; 
       }
        public static AppSettings getInstance(Context context) {
          if (sInstance == null) { 
            sInstance = new AppSettings(context);
     } 
      return sInstance; 
     }
 }

像上面代码中如此的单例,借使大家在调用 getInstance(Context context)措施时会传入context参数是activity,service等上下文,就能招致内存泄漏

Activity为例,当我们运营一个Activity,并调用getInstance(Context context)措施去获得AppSettings的单例,传入Activity.this作为context,这样AppSettings类的单例sInstance就具有了Activity的援引,当我们脱离Activity时,该Activity就从未有过用了,不过因为sIntance作为静态单例(在应用程序的总体生命周期中留存)会持续有所那些Activity的援用,导致那一个Activity对象不可能被回收释放,那就导致了内部存款和储蓄器走漏。

为了制止那样单例导致内部存款和储蓄器败露,咱们能够将context参数改为全局的上下文:

    private AppSettings(Context context) {
        this.mContext = context.getApplicationContext();
    }

全局的上下文Application Context不怕应用程序的上下文,和单例的生命周期同样长,这样就幸免了内部存款和储蓄器泄漏。

单例格局对应应用程序的生命周期,所以大家在组织单例的时候尽量幸免使用Activity的上下文,而是利用Application的上下文。

致使内部存款和储蓄器走漏败露的最大旨原理正是叁个指标具有了超过本人生命周期以外的对象强引用导致该对象不大概被符合规律排放物回收;可以窥见,应用内部存款和储蓄器败露是个十三分为难重要的难题,大家亟须讲究。

编辑:mg4377娱乐手机版 本文来源:内部存款和储蓄器走漏优化,常见内部存款和储

关键词: Android 内存 记录