Android 内存泄漏原因
Android 手机给应用分配的堆内存通常是8 M 左右, 如果内存处理不当很容易造成 OOM (OutOfMemoryError),OOM 主要由于一下这些原因引起的:
1. 数据库 Cursor 没有关闭。
当我们使用完数据库之后,一定要调用 close() 关闭数据库,并释放资源。
2. ListView 等列表没有使用 ViewHolder 。
@Override
public View getView(int position, View convertView, ViewGroup parent) {
ViewHolder vHolder = null;
//如果convertView对象为空则创建新对象,不为空则复用
if (convertView == null) {
convertView = inflater.inflate(..., null);
// 创建 ViewHodler 对象
vHolder = new ViewHolder();
vHolder.img= (ImageView) convertView.findViewById(...);
vHolder.tv= (TextView) convertView
.findViewById(...);
// 将ViewHodler保存到Tag中
convertView.setTag(vHolder);
} else {
//当convertView不为空时,通过getTag()得到View
vHolder = (ViewHolder) convertView.getTag();
}
// 给对象赋值,修改显示的值
vHolder.img.setImageBitmap(...);
vHolder.tv.setText(...);
return convertView;
} static class ViewHolder {
TextView tv;
ImageView img;
}
3. 未取消注册广播接收器。
registerReceiver() 和 unregisterReceiver() 必须成对使用, 通常是在 onDestory () 方法中取消注册广播接收器。
4. IO流未及时关闭。
5. Bitmap 使用后未调用 recycle()。
6. 线程也是造成内存泄漏的一个重要源头。线程产生内存泄漏主要是由于线程的生命周期不可控。我们来看看下面这段代码:
public class MyActivity extends Activity {
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.main);
new MyThread().start();
}
private class MyThread extends Thread{
@Override
public void run() {
super.run();
//耗时的操作
}
}
}
假设MyThread 的 run 函数是一个很费时的操作,当调用 finish 的时候 Activity 会被销毁掉吗? 事实上 , MyThread 是Activity的内部类,所以 MyThread 中保存了 Activity 的一个引用,当 run 方法没有执行完之前, MyThread 是不会被销毁的,因此它所引用的Activity 也不会被销毁,因此就出现了内存泄露问题。
7. 单例造成的内存泄漏。由于单例模式的静态特性是的生命周期跟应用程序的生命周期一样长,因此很容易由于使用不当造成内存泄漏。例如:
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;
}
}
这里如果传入的是 Activity 的 Context ,当该Context的Activity退出后,但是由于 Context 被单利对象引用,所以导致 Activity 无法被回收,就造成了内存泄漏。
8. 创建一个非静态内部类的静态实例造成的内存泄漏。
public class MainActivity extends AppCompatActivity {
private static TestResource mResource = null;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_main);
if(mManager == null){
mManager = new TestResource();
}
//...
}
class TestResource {
//...
}
}
因为非静态内部类会持有外部类的引用,而该非静态内又创建了一个静态实例,该静态实例的生命周期与应用的生命周期一样长,这就导致了静态实例一直会持有 Activity 的引用而造成的内存泄漏。
Android 内存泄漏原因的更多相关文章
- Android内存泄漏原因
这段时间调试APP的时候,发现程序在加载了过多的bitmap后会崩溃.查看了日志,原来是发生了内存溢出(OOM).第一次遇到这样的问题,那就慢慢排查吧. 内存优化可以参考胡凯大神的博客Android内 ...
- Android内存泄漏的各种原因详解
转自:http://mobile.51cto.com/abased-406286.htm 1.资源对象没关闭造成的内存泄漏 描述: 资源性对象比如(Cursor,File文件等)往往都用了一些缓冲,我 ...
- 【转】android 内存泄漏相关收藏博客。
关于android内存泄漏的研究 博客建了几个月,都没有去写,一是因为当时换工作,然后又是新入职(你懂的,好好表现),比较忙:二是也因为自己没有写博客的习惯了.现在还算是比较稳定了,加上这个迭代基 ...
- 关于android内存泄漏的研究
博客建了几个月,都没有去写,一是因为当时换工作,然后又是新入职(你懂的,好好表现),比较忙:二是也因为自己没有写博客的习惯了.现在还算是比较稳定了,加上这个迭代基本也快结束了,有点时间来写写博客.好了 ...
- Android 内存泄漏优化汇总
android内存泄漏优化摘要 博客分类: android android内存溢出OutOfMemoryError . android移动应用程序的内存分配一般是8凯瑟琳约,不正确地假定处理内存处理非 ...
- Android内存泄漏检测利器:LeakCanary
Android内存泄漏检测利器:LeakCanary MAR 28TH, 2016 是什么? 一言以蔽之:LeakCanary是一个傻瓜化并且可视化的内存泄露分析工具 为什么需要LeakCanary? ...
- Android 内存泄漏分析与解决方法
在分析Android内存泄漏之前,先了解一下JAVA的一些知识 1. JAVA中的对象的创建 使用new指令生成对象时,堆内存将会为此开辟一份空间存放该对象 垃圾回收器回收非存活的对象,并释放对应的内 ...
- [Android]Android内存泄漏你所要知道的一切(翻译)
以下内容为原创,欢迎转载,转载请注明 来自天天博客:http://www.cnblogs.com/tiantianbyconan/p/7235616.html Android内存泄漏你所要知道的一切 ...
- Android内存泄漏的检测流程、捕捉以及分析
https://blog.csdn.net/qq_20280683/article/details/77964208 Android内存泄漏的检测流程.捕捉以及分析 简述: 一个APP的性能,重度关乎 ...
随机推荐
- echarts动态刷新数据
在这次的项目中图表显示的部分比较多,这边给分享下用到的图表的数据刷新 饼图最后的效果 先看下 前端部分 <div div style="height: 40%; width: 17.5 ...
- 零基础Linux入门学习方法--如何做好笔记及长效知识复习记忆
“工欲善其事必先利其器”. 此次学习的0基础教材为刘遄(Liu Chuán)老师的<Linux就该这么学>.学习目的是通过RHCE认证.有关RHCE认证介绍会在认识Linux及红帽认证中记 ...
- 『题解』洛谷P2170 选学霸
更好的阅读体验 Portal Portal1: Luogu Description 老师想从\(N\)名学生中选\(M\)人当学霸,但有\(K\)对人实力相当,如果实力相当的人中,一部分被选上,另一部 ...
- Linux基于webRTC的二次开发(二) 实现远程桌面共享
webRTC中的desktop_capture模块提供了捕获桌面和捕获窗口的相关功能,而实现远程桌面共享功能需要将desktop_capture捕获的画面作为peerconnection的视频源,下面 ...
- JSON《===》JavaBean的相互转换
1.JSON的作用和好处 在JavaWeb项目中前后端直接的交互,接口之间的对接等等,基本离不开JSON. JSON: 全称JavaScript Object Notation(JavaScript ...
- linux中dd相关命令骚操作
一.dd如何快速将磁盘写满 方法一: dd if=/dev/zero of=/tmp/file bs=1G count=10 # 参数解释 1. if=文件名:输入文件名,缺省为标准输入.即指定源文件 ...
- C++中对封装的语法支持——重载运算符
重载运算符 1.对于自定义类型,编译器不知道运算规则,而重载运算符会将两个对象相加转换为函数调用. 2.运算符重载转换的函数调用,函数名字是固定的规则. (1) 如果重载+号运算符,函数名字就是:op ...
- Swoole跟thinkphp5结合开发WebSocket在线聊天通讯系统
ThinkPHP使用Swoole需要安装 think-swoole Composer包,前提系统已经安装好了Swoole PECL 拓展* tp5的项目根目录下执行composer命令安装think- ...
- Pashmak and Parmida's problem(树状数组)
题目链接:http://codeforces.com/contest/459/problem/D 题意: 数列A, ai表示 i-th 的值, f(i,j, x) 表示[i,j]之间x的数目, 问:当 ...
- 访问formData的数据
vant-ui 的 Uploader 上传图片时,用到formData let fd = new FormData(); fd.append('upImgs', file.file); postIma ...