我是靠谱客的博主 忧虑大地,这篇文章主要介绍Android中的内存泄漏Android中的内存泄漏,现在分享给大家,希望可以做个参考。

**

Android中的内存泄漏

**

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

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
@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 {

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
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

复制代码
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
{ 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中内容请搜索靠谱客的其他文章。

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

评论列表共有 0 条评论

立即
投稿
返回
顶部