文档章节

Android中常见的内存泄漏 memory leak

MonkeySun
 MonkeySun
发布于 2016/11/14 21:32
字数 1243
阅读 89
收藏 0

四种主要的情况:

1、Activity对象未被回收

2、集合对象造成的泄漏

3、资源对象没关闭造成内存泄漏

4、使用对象池避免频繁创建对象

--------------------------------------------------------------------------------------

 一. Activity对象未被回收

 1.1 静态变量引用Activity对象

   通过静态变量引用Activty对象时,会导致Activty对象所占内存内漏。主要是因为,静态变量是驻扎在JVM的方法区,因此,静态变量引用的对象是不会被GC回收的。即最终导致Activity对象不被回收,从而也就造成内存泄漏。

     看个简单例子,比如说,你应用启动Activty的场景很多,你希望定义一个工具类Util.Java,

在这个类中,定义一个启动Activty的方法startActivity(Class nextActivity);以此来简化启动Activty的代码。

另外,加入你当前的Activty启动另一个Activty的代码使用率也特别高。为了使得参数尽可能的少,你提供setFirstActivty,保存当前的Activty。

在当前的Activty中,只需在onCreate中调用Util.setFirstActivity(this);,在需要启动另一个Activty处调用Util.startActivity(SecondActivity.class);。

在上面代码中,如果当前的Activty不再使用 且Util中的sActivity对象没有更改,会导致当前Activty一直驻留在内存中。

 1.2 静态View   

有时,当一个Activity经常启动,但是对应的View读取非常耗时,我们可以通过静态View变量来保持对该Activity的rootView引用。

但是要注意,一旦View attach到我们的Window上,就会持有一个Context(即Activity)的引用。

而我们的View有事一个静态变量,所以导致Activity不被回收。但是在使用静态View时,需要确保在资源回收时,将静态View detach掉。

 1.3 内部类

我们知道,非静态内部类持有外部类的一个引用。因此,如果我们在一个外部类中定义一个静态变量,这个静态变量是引用内部类对象。将会导致内存泄漏!因为这相当于间接导致静态引用外部类。

 1.4 匿名类

 1.5 Handler

在Java中,匿名内部类会引用外部类对象。而静态内部类不会引用外部类对象.

这个mHandler会持有外部类(MainActivity)实例的引用,因为它处于一个对象的上下文中

 1.6 Threads和TimerTask

Threads和Timer导致内存泄漏的原因跟内部类一样。虽然在新的线程中创建匿名类,但是只要是匿名类/内部类,它都会持有外部类引用.

这里内存泄漏在于Timer和TimerTask没有进行Cancel().

 1.7 监听器

当我们需要使用系统服务时,比如执行某些后台任务、为硬件访问提供接口等等系统服务。我们需要把自己注册到服务的监听器中。

然而,这会让服务持有 activity 的引用,如果程序员忘记在 activity 销毁时取消注册,那就会导致 activity 泄漏了.在onDestroy方法里注销监听器。

 ---------------------------------------------------------------------------------------

2、集合对象造成的泄漏

当我们定义一个静态的集合类时,请注意,这可能会导致内存泄漏!前面我们提到过,静态变量所引用的对象是不会被回收掉的。而我的静态集合类中,包含有大量的对象,这些对象不会被回收。另外,如果集合中保存的对象又引用到了其他的大对象,如超长字符串、Bitmap、大数组等,很容易造成OOM。

---------------------------------------------------------------------------------------

3、资源对象没关闭造成内存泄漏

当我们打开资源时,一般都会使用缓存。比如读写文件资源、打开数据库资源、使用Bitmap资源等等。当我们不再使用时,应该关闭它们,使得缓存内存区域及时回收。虽然有些对象,如果我们不去关闭,它自己在finalize()函数中会自行关闭。但是这得等到GC回收时才关闭,这样会导致缓存驻留一段时间。如果我们频繁的打开资源,内存泄漏带来的影响就比较明显了。

---------------------------------------------------------------------------------------

4、使用对象池避免频繁创建对象

在我们需要频繁创建使用某个类时,或者是在for循环里面创建新的对象时,导致JVM不断创建同一个类。

我们知道,在使用Message对象时,不是直接new出来的,而是通过obtain方法获取,以及recycle方法回收。

这是典型的享元模式。我们可以通过使用对象池来实现.

 

主要原因:

长生命周期的对象持有短生命周期对象的引用就很可能发生内存泄露。

 

 

© 著作权归作者所有

共有 人打赏支持
MonkeySun
粉丝 0
博文 3
码字总数 2174
作品 0
昌平
私信 提问
Android Activity / Fragment内存泄露引论

 Android Activity / Fragment内存泄露引论 Android发生OOM(OutOfMemoryError)问题的重要因素是编程设计不佳的代码出现内存泄露(Leak)造成Android分配的内存紧张。关于内存泄漏的问题...

开开心心过
2017/10/19
0
0
Android应用内存泄漏的定位、分析与解决策略

Hello,大家好,我是Clock。翻了一下简书,发现有一个多月没有更新博客,本来今天打算和妹纸去电影院看《你的名字》,然后再去到处浪的。 结果因为妹纸公司临时有事,她不得不回公司一趟......

D_clock爱吃葱花
06/29
0
0
Android:内存控制及OOM处理

OOM(内存溢出)和Memory Leak(内存泄露)有什么关系? OOM可能是因为Memory Leak,也可能是你的应用本身就比较耗内存(比如图片浏览型的)。所以,出现OOM不一定是Memory Leak。 同样,Mem...

Xushao
2013/05/07
0
1
【android测试】值得学习的android测试知识连接

Android应用程序的debug属性: http://blog.csdn.net/hudashi/article/details/8698142 彻底解决Android 应用方法数不能超过65535的问题 http://blog.csdn.net/yuanzeyao/article/details/418......

beijing_zbs
2014/12/02
0
0
用了WifiManager这么多年,今天才知道彻底用错了

用了WifiManager这么多年,今天才知道彻底用错了 snowdream - Impossible is nothing!2017-11-141 阅读 android 作者:snowdream Email:yanghui1986527#gmail.com Github: https://github.c......

snowdream - Impossible is nothing!
2017/11/14
0
0

没有更多内容

加载失败,请刷新页面

加载更多

一个案例彻底弄懂如何正确使用 mysql inndb 联合索引

摘要: 有一个业务是查询最新审核的5条数据 ```sql SELECT `id`, `title` FROM `th_content` WHERE `audit_time` < 1541984478 AND `status` = 'ONLINE' ORDER BY `audit_time` D. 原来链接 ......

阿里云官方博客
10分钟前
1
0
详解如何用爬虫采集视频播放量数据(以腾讯视频为例)

现代社会提到大数据大家都知道这是近几年才形成的对于数据相关的新名词,在1980年,著名未来学家阿尔文·托夫勒便在 《第三次浪潮》一书中,将大数据热情地赞颂为“第三次浪潮的 华彩乐章”...

技术阿飞
16分钟前
1
0
区块链时代的拜占庭容错:Tendermint(二)

原文题目:《Tendermint: Byzantine Fault Tolerance in the Age of Blockchains》 原文作者:Ethan Buchman 翻译:饶云坤 校对:傅晓波 本文为节选 以下为正文: 本章阐述Tendermint共识算法...

万向区块链
29分钟前
0
0
AS连接网易Mumu模拟器

1、安装模拟器 打开这个网址现在模拟器然后安装 http://mumu.163.com/ 2、安装完成后启动模拟器 3、进入模拟器安装目录 例如本机的安装目录:C:\Program Files (x86)\MuMu\emulator\nemu\vmo...

HGMrWang
35分钟前
9
0
设计要做到扩展性强还挺难的

概述 在日常开发中,有时候你的上司会跟你说,这个模块的设计扩展性要高。把这句话说出来很简单,但是要做到则非常难。导致难的其中一个因素是: 你不熟悉这个行业的业务的玩法 我举个例子来...

Sam哥哥聊技术
37分钟前
3
0

没有更多内容

加载失败,请刷新页面

加载更多

返回顶部
顶部