内存泄露方式有哪些和如何查询内存泄露?
内存泄露的方式
1、查询数据库而没有关闭Cursor
在Android中,Cursor是很常用的一个对象,但在写代码是,经常会有人忘记调用close, 或者因为代码逻辑问题状况导致close未被调用。通常,在Activity中,我们可以调用startManagingCursor或直接使用managedQuery让Activity自动管理Cursor对象。但需要注意的是,当Activity介绍后,Cursor将不再可用!若操作Cursor的代码和UI不同步(如后台线程),那没需要先判断Activity是否已经结束,或者在调用OnDestroy前,先等待后台线程结束。除此之外,以下也是比较常见的Cursor不会被关闭的情况:虽然表面看起来,Cursor.close()已经被调用,但若出现异常,将会跳过close(),从而导致内存泄露。
导致内存泄露的地方:
try {
Cursor c = queryCursor();
int a = c.getInt(2);
......
} catch (Exception e) {
}
所以,我们的代码应该以如下的方式编写:
Cursor c = queryCursor();
try {
int a = c.getInt(2);
......
} catch (Exception e) {
} finally {
c.close(); //在finally中调用close(), 保证其一定会被调用
}
2. 调用registerReceiver后未调用unregisterReceiver().
在调用registerReceiver后,若未调用unregisterReceiver,其所占的内存是相当大的。
而我们经常可以看到类似于如下的代码:
这是个很严重的错误,因为它会导致BroadcastReceiver不会被unregister而导致内存泄露。
registerReceiver(new BroadcastReceiver() {
...
}, filter); ...
3. 未关闭InputStream/OutputStream
在使用文件或者访问网络资源时,使用了InputStream/OutputStream也会导致内存泄露。
4. Bitmap使用后未调用recycle()
根据SDK的描述,调用recycle并不是必须的。但在实际使用时,Bitmap占用的内存是很大的,所以当我们不再使用时,尽量调用recycle()以释放资源。
5. Context泄露
这是一个很容易的内存泄露的情况。
看一下以下代码:
private static Drawable sBackground;
@Override
protected void onCreate(Bundle state) {
super.onCreate(state);
TextView label = new TextView(this);
label.setText("Leaks are bad");
if (sBackground == null) {
sBackground = getDrawable(R.drawable.large_bitmap);
}
label.setBackgroundDrawable(sBackground);
setContentView(label);
}
在这段代码中,我们使用了一个static的Drawable对象。这通常发生在我们需要经常调用一个Drawable,而其加载又比较耗时,不希望每次加载Activity都去创建这个Drawable的情况。此时,使用static无疑是最快的代码编写方式,但是其也非常的糟糕。当一个Drawable被附加到View时,这个View会被设置为这个Drawable的callback (通过调用Drawable.setCallback()实现)。这就意味着,这个Drawable拥有一个TextView的引用,而TextView又拥有一个Activity的引用。这就会导致Activity在销毁后,内存不会被释放。
如何查询内存泄露
1、首先确定是否有内存泄露及哪个程序造成。
a、内存泄露已弹出out of memory对话框的情况。
这种情况很简单,直接看对话框就知道是哪个应用的问题了。然后再分析该应用是否是因为内存泄露造成的out of memory对话框。
b、对于有内存泄露,但没造成弹出out of memory对话框的情况
使用《Android中如何查看内存》中介绍的各种方法进行分析,确定是否有内存泄露以及是哪个进程造成的内存泄露。
2、生成hprof文件,用MAT进行分析。
生成hprof文件可以在DDMS选中进程点击窗口左上角的"dump hprof file"按钮来直接生成,也可以通过在程序加代码中来生成
代码2:
void generateHprof()
{
String packageName=getApplicationInfo().packageName;
String hpFilePath="/data/data/"+packageName+"/input.hprof";
try {
//Debug.dumpHprofData("/sdcard/input.hprof");
Debug.dumpHprofData(hpFilePath);
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
建议使用代码生成hprof,然后使用《Android内存泄露利器(hprof篇)》中的工具自动提取多个hprof文件,然后用MAT进行比较分析。在MAT导入.hprof文件以后,MAT会自动解析并生成报告,点击Dominator Tree,并按Package分组,选择自己所定义的Package类,比较各个类在不同时期的Retained Heap,找出可疑类,然后选择该类,点右键,选中show retained Set 项,参看Retained Heap的详细信息,进一步找出嫌疑项。
3、在代码中查找内存泄露。
根据在MAT找到的内存泄露信息,参照《Android内存泄漏简介》进一步在内存中查找内存泄露的原因并解决。另外如果代码很简单,可以直接参照《Android内存泄漏简介》在内存中查找内存泄露的原因并解决。
如果您有更好的方式我们一起完善。。。。3q
内存泄露方式有哪些和如何查询内存泄露?相关推荐
- Objective-C入门解读与内存管理方式
Objective-C入门 Objective-C入门(A First Look at Objective-C) 转自: http://www.fish888.com/Objective-C-t684 ...
- 操作系统--内存管理方式
"碎片的内存"描述一个系统中所有不可用的空闲内存.这些资源之所以仍然未被使用,是因为负责分配内存的分配器使这些内存无法使用.这一问题通常都会发生,原因在于空闲内存以小而不连续方式出 ...
- c语言的内存管理方式,c语言内存管理
2017-08-23 作用域 一个C语言变量的作用域可以是代码块 作用域,函数作用域或者文件作用域.代码块是{}之间的一段代码. auto 自动变量 一般情况下代码块内部定义的变量都是自动变量.当然也 ...
- LINQ学习笔记之四:查询内存对象
附上WORD文档,从这里下载. 查询内存对象 这一章中主要介绍了使用LINQ查询内存对象的一些基本语法.在下一章将会有更高级的用法介绍.本章中的示例数据是一个简单的出版社信息.这里是数据文件.下面的图 ...
- 在Android开发中,有哪些好的内存优化方式?如何避免 Out Of Memory(OOM) ?
在Android中,一个Process 只能使用16M内存,要是超过了这个限定就会跳出这个异常. 那么,开发中,有哪些措施能避免这个问题呢?不仅仅是Bitmap的处理,其他方面也会导致OOM.有哪些 ...
- C/C++内存分配方式 .
1.内存分配方式 内存分配方式有三种: [1]从静态存储区域分配.内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在.例如全局变量,static变量. [2]在栈上创建.在执行函数时 ...
- C++内存分配方式、内存错误及其对策
C++内存分配方式.内存错误及其对策 内存分配方式有三种: 从静态存储区域分配.内存在程序编译的时候就已经分配好,这块内存在程序的整个运行期间都存在.例如全局变量,static变量. 在栈上创建.在执 ...
- MFC 教程【10_内存分配方式和调试机制 】
内存分配方式和调试机制 M内存分配 内存分配函数 MFCWin32或者C语言的内存分配API,有四种内存分配API可供使用. Win32的堆分配函数 每一个进程都可以使用堆分配函数创建一个私有的堆── ...
- 终于明白那些年知其然而不知其所以然的iOS内存管理方式
终于明白那些年知其然而不知其所以然的iOS内存管理方式 前言 从我开始学习iOS的时候,身边的朋友.网上的博客都告诉我iOS的内存管理是依靠引用计数的,然后说引用计数大于1则对象保存在内存的堆中而引用 ...
最新文章
- shell命令之---Linux文件权限
- 蔡氏电路matlab程序,蔡氏电路matlab仿真报告
- openCV基础数据结构介绍
- tensorflow入门基础
- SpringMVC使用及知识点提炼
- ASP VNext 开源服务容错处理库Polly
- Android之网络请求通过协程+okhttp的没有做网络异常处理导致程序奔溃问题
- 团队项目电梯会议视频
- BZOJ 2878: [Noi2012]迷失游乐园( 树形dp )
- 【手写数字识别】基于matlab GUI贝叶斯最小错误率手写数字识别【含Matlab源码 308期】
- python怎样编写定时程序_如何用Python写一个每分每时每天的定时程序
- matlab2014如何获得hostid,关于如何修改hostid的问题
- ipad android开迅视频播放器,迅课视频播放器
- CSS4day(圆角边框,阴影,浮动详解及其示例)
- 计算机与音乐教育留学,计算机与儿童创新音乐教育
- 计算机用户密码无法输入,电脑数字密码输入不了怎么办
- STL--函数对象学习
- 使用JLINK下载程序可以,但是调试不行
- 石家庄神月软件java笔试
- 兼容性测试,电脑的显示器分辨率大全
热门文章
- 在线图书销售系统顺序图_良心好用的在线学习工具,你知道和不知道的,这里都有~...
- yum update和yum upgrade的真正区别
- securecrt能输入命令吗?
- Java核心技术卷一
- Keil环境添加STC系列单片机
- An unexpected error has been detected by Java Runtime Environment
- Magic Leap 价值 20 多亿美元的 AR 幻梦,现在醒了
- 【ACM】HDU.2094 产生冠军 【STL-map】
- 测绘——如何在win10环境下安装CAD2006+CASS7.0
- 编写电话号码查询系统