我是靠谱客的博主 忧虑大地,最近开发中收集的这篇文章主要介绍Android中的内存泄漏Android中的内存泄漏,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

**

Android中的内存泄漏

**

Android中的内存泄漏:
概念:程序在申请内存后,当该内存不需再使用但却无法被释放 & 归还给程序的现象,对应用程序的影响,容易使得应用程序发生内存溢出,即 OOM,其实也就是当一个对象使用完毕后,被另外一个对象持有并引用,导致无法被回收的现象叫内存泄漏。
内存泄露的危害
  内存泄露的危害就是会使虚拟机占用内存过高,导致OOM(内存溢出),程序出错。
  对于Android应用来说,就是你的用户打开一个Activity,使用完之后关闭它,内存泄露;又打开,又关闭,又泄露;几次之后,程序占用内存超过系统限制,FC。
导致内存泄漏的情况:可以说,书写代码的过程中任何情况都会出现内存泄漏。但,总体来分析的话,有以下几个原因:
一:线程导致的内存泄漏:在Activity 销毁之前,线程的任务并没有执行完毕,就会导致内存泄漏。
解决办法:将AsyncTask和Runnable类独立出来或者使用静态内部类,这样便可以避免内存泄漏。
举例:
public class MainActivity extends AppCompatActivity {

@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
new Thread(new MyRunnable()).start();
new MyAsyncTask(this).execute();
}
class MyAsyncTask extends AsyncTask<Void, Void, Void> {
// ...
public MyAsyncTask(Context context) {
// ...
}
@Override
protected Void doInBackground(Void... params) {
// ...
return null;
}
@Override
protected void onPostExecute(Void aVoid) {
// ...
}
}
class MyRunnable implements Runnable {
@Override
public void run() {
// ...
}
}

}

二 :单例模式导致的内存泄漏:因为单例的静态属性使得生命周期和应用程序的生命周期一样长。若1个对象已不需再使用而单例对象还持有该对象的引用,那么该对象将不能被正常回收从而 导致内存泄漏。
解决办法:使用Appaction中context上下文,因为这样不管传入什么Context最终将使用Application的Context,而单例的生命周期和应用的一样长,这样就防止了内存泄漏。
// 使用了单例模式举例:

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;
}

};

三:Handler造成的内存泄漏:Handler是处理进程间通信的机制,那么,当MainActivity结束时,未处理的消息持有handler的引用,而handler又持有它所属的外部类也就是MainActivity的引用。这条引用关系会一直保持直到消息得到处理,这样阻止了MainActivity被垃圾回收器回收,从而造成了内存泄漏。
解决办法:1:将Handler独立出来。2:将Handler声明为静态类 。3:在关闭Activity的时候停掉你的后台线程。线程停掉了,就相当于切断了Handler和外部连接的线,Activity自然会在合适的时候被回收。
举例:注意这个时候Handler中增加了一个对Activity的弱引用(WeakReference)。
static class MyHandler extends Handler

{
WeakReference<Activity> mWeakReference;
public MyHandler(Activity activity)
{
mWeakReference=new WeakReference<Activity>(activity);
}
@Override
public void handleMessage(Message msg)
{
final Activity activity=mWeakReference.get();
if(activity!=null)
{
if (msg.what == 1)
{
noteBookAdapter.notifyDataSetChanged();
}
}
}
}

四:使用资源导致的内存泄漏: 对于资源的使用(如 广播BraodcastReceiver、文件流File、数据库游标Cursor、图片资源Bitmap等),若在Activity销毁时无及时关闭 / 注销这些资源,则这些资源将不会被回收,从而造成内存泄漏。
解决办法:资源使用完毕后,(Activity销毁)一定要及时关闭/销毁资源。
五:集合类使用导致的内存泄漏:集合容器中的内存泄露 我们通常把一些对象的引用加入到了集合容器(比如ArrayList)中,当我们不需要该对象时,并没有把它的引用从集合中清理掉,这样这个集合就会越来越大。导致内存泄漏,甚至于程序崩溃。
解决方法:在退出程序之前,或使用完集合时,将集合里的东西clear,然后置为null,再退出程序。
六:webView造成的内存泄漏:当我们不要使用WebView对象时,应该调用它的destory()函数来销毁它,并释放其占用的内存,否则其长期占用的内存也不能被回收,从而造成内存泄露。
解决办法:不再需要使用WebView时,及时使用destory销毁它。
七:.Static关键字修饰的成员变量导致的内存泄漏:若使被 Static 关键字修饰的成员变量 引用耗费资源过多的实例(如Context),则容易出现该成员变量的生命周期 > 引用实例生命周期的情况,当引用实例需结束生命周期销毁时,会因静态变量的持有而无法被回收,从而出现内存泄露。
解决办法:尽量避免 Static 成员变量引用资源耗费过多的实例。
如何检测内存泄漏 ,如何优化内存泄漏:
MAT(Memory Analysis Tools)
Heap Viewer
Allocation Tracker
Android Studio 的 Memory Monitor LeakCanary

最后

以上就是忧虑大地为你收集整理的Android中的内存泄漏Android中的内存泄漏的全部内容,希望文章能够帮你解决Android中的内存泄漏Android中的内存泄漏所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(70)

评论列表共有 0 条评论

立即
投稿
返回
顶部