欢迎访问自动发外链网站,大量seo自动发布外链工具与案例

用Android防止内存泄漏的八种方法

作者:jcmp      发布时间:2021-04-30      浏览量:0
原始地址。在上次Android内存泄漏中

原始地址。

在上次Android内存泄漏中,我们讨论了容易发生内存泄漏的八种代码类型。其中最严重的是活动对象的泄漏,因为它占用了大量的系统内存。不管内存泄漏的代码表示形式如何,核心问题是:

幸运的是,一旦泄漏发生并找到,修复方法就相当简单。

私有静态MainActivity活动;voidsetStaticActivity(){Activity=this;}

构造包含活动对象的静态变量很容易导致内存泄漏,因为静态变量是全局存在的,因此在MainActivity生命周期结束时仍然保留引用。本文开发人员有理由使用它,所以我们需要正确地发布引用,这样垃圾收集机制就可以在被销毁时回收它。

Android提供了一个特殊的集合集合https://developer.android.Com/reference/java/lang/ref/package-summary.HTML#类允许开发人员控制引用的“强度”。ActivityObject泄漏的原因是,当需要销毁它时,它仍然是强引用的,并且只要强引用存在,就无法恢复它。

弱引用不会阻止对象的内存释放,因此即使存在弱引用,也可以回收对象。

私有静态WeakReferenceactivityReference;voidsetStaticActivity(){activityReference=newWeakReference(此);}

二、静态视图

静态变量持有View

私有静态视图视图;voidsetaticView(){view=findViewById(R.id.sv_按钮);}

由于持有其宿主持有其宿主Activity的引用,导致的问题与Activity一样严重。弱引用是一种有效的解决方案,但在生命周期结束时有另一种方法可以清除引用,而且Activity#onDestory()方法非常适合将引用保留为空。

私有静态视图视图;@Overridepublic void onDesty(){Super.onDesty();if(view!=null){unsetStaticView();}}voidunsetStaticView(){view=null;

三、内部类

这种泄漏

私有静态对象内部;VoidcreateInnerClass(){class InnerClass{}innerClass();}

类似于上述两种情况,开发人员必须小心使用较少的非静态内部类,因为非静态内部类包含对外部类的隐式引用,这很容易导致意外泄漏。但是,内部类可以访问外部类的私有变量,只要我们关注生命周期的引用,就可以避免事故的发生。

可以保存内部类的成员变量。

私有对象内部;voidcreateInnerClass(){class InnerClass{}innerClass()内;}

4,匿名类

都是由静态成员变量直接或间接地通过对活动的链式引用导致的。这一次我们使用AsyncTask。

voidstartAsyncTask(){新AsyncTask(){@重载受保护的voiddoInBackplace(void.(Params){while(True);}}.Execute();}

Handler

voidcreateHandler(){新Handler(){新Handler(){新的Handler(){新的@覆盖公共无效的handleMessage(Message){Super.handleMessage(Message);};}.postDelayed(新的runnable(){@重载public voidrun());},long.max_value>>1);}

线程

voidscheduleTimer(){新计时器()。调度(新的TimerTask(){@overpublic voidrun(){while(True);},Long.MAX_value>1);}

都是由匿名类引起的。匿名类是特殊的内部类-它们编写得更简洁。当需要一次特殊子类时,Java提供的语法糖分使表达式最小化。这种精彩而懒惰的写作很容易导致漏字。与内部类一样,只要内部类不跨越生命周期,内部类就完全没有问题。但是,这些类用于生成后台线程,这些线程是全局的,包含对创建者的引用(即对匿名类的引用),而后者又保存对外部类的引用。线程可以运行很长时间,因此始终保持对活动的引用使得在销毁时无法恢复。这一次,我们无法通过删除静态成员变量来解决这个问题,因为线程与应用程序生命周期相关。为了避免泄漏,我们必须放弃简单和懒惰的编写,将子类声明为静态内部类。

所以对于AsyncTask

私有静态类NimbleTask扩展AsyncTask{@重载受保护的voiddoInBackplace(void.Params){while(True);}}voidstartAsyncTask(){新的NimbleTask().execute();}

Handler

private静态类NimbleHandler扩展Handler{@overpublic voidhandleMessage(消息消息){Super.handleMessage(Message);}私有静态类NimbleRunnable实现runnable{@overpublic voidrun(){while(True);}}voidcreateHandler(){新的NimbleHandler().postDelayed(新的NimbleRunnable(),Long.MAX_value>>1);}

TimerTask

私有静态类NimbleTimerTask扩展TimerTask@overpublic voidrun(){while(True);}}scheduleTimer(){新计时器().ScheduleTimer(){新计时器().ScheduleTimer(){新计时器(),Long。MAX_value>>1);}

但是,如果坚持使用匿名类,只需在生命周期结束时中断线程即可。

私有线程;@Overridepublic voidonDesty(){Super.onD及第();if(线程!=NULL){线程.中断();}}voidspawnThread(){线程=新线程(){\@overoverpublic voidrun(){while(!isInterrupy(){}}).start();}

五、传感器管理器

这种泄漏

无效寄存器Listener(){SensorManager传感器管理器=(SensorManager)getSystemService(传感器_服务);传感器传感器=五、

不正确地使用Android系统服务很容易导致泄漏。为了使活动与服务交互,我们使用活动作为侦听器,并在传递事件和回调中形成引用链。只要活动保持已注册的侦听状态,引用就会一直保持,并且内存不会释放。

私有SensorManager感觉管理器;私有传感器;@Overridepublic void onDesty(){Super.onDesty();if(传感器!=NULL){unRegierListener();}}voidunRegierListener(){senorManager.UnRegierListener(此传感器);}

>6。我们已经研究了

活动泄漏的所有情况,其他的情况也是一样的。建议在今后遇到类似情况时使用相应的解决方案。只要内存泄漏一次,通过详细的检查,很容易解决,防止故障发生。

是时候成为最佳实践了!