android内存泄露
来源:互联网 发布:shutting down mysql 编辑:程序博客网 时间:2024/06/14 12:06
转自:http://jiajixin.cn/2015/01/06/memory_leak/
概念
根搜索算法
Android虚拟机的垃圾回收采用的是根搜索算法
。GC会从根节点(GC Roots)开始对heap进行遍历。到最后,部分没有直接或者间接引用到GC Roots的就是需要回收的垃圾,会被GC回收掉。
根搜索算法相比引用计数法很好的解决了循环引用的问题。举个例子,Activity有View的引用,View也有Activity的引用,之前我还尝试去源代码里找Activity何时和View断开连接是大错特错了。当Activity finish掉之后,Activity和View的循环引用已成孤岛,不再引用到GC Roots,无需断开也会被回收掉。
内存泄漏
Android内存泄漏
指的是进程中某些对象(垃圾对象)已经没有使用价值了,但是它们却可以直接或间接地引用到gc roots导致无法被GC回收。无用的对象占据着内存空间,使得实际可使用内存变小,形象地说法就是内存泄漏了。
场景
- 类的静态变量持有大数据对象
静态变量长期维持到大数据对象的引用,阻止垃圾回收。 - 非静态内部类的静态实例
非静态内部类会维持一个到外部类实例的引用,如果非静态内部类的实例是静态的,就会间接长期维持着外部类的引用,阻止被回收掉。 - 资源对象未关闭
资源性对象如Cursor、File、Socket,应该在使用后及时关闭。未在finally中关闭,会导致异常情况下资源对象未被释放的隐患。 - 注册对象未反注册
未反注册会导致观察者列表里维持着对象的引用,阻止垃圾回收。 Handler
临时性内存泄露
Handler通过发送Message与主线程交互,Message发出之后是存储在MessageQueue中的,有些Message也不是马上就被处理的。在Message中存在一个 target,是Handler的一个引用,如果Message在Queue中存在的时间越长,就会导致Handler无法被回收。如果Handler是非静态的,则会导致Activity或者Service不会被回收。
由于AsyncTask内部也是Handler机制,同样存在内存泄漏的风险。
此种内存泄露,一般是临时性的。
预防
- 不要维持到Activity的长久引用,对activity的引用应该和activity本身有相同的生命周期。
- 尽量使用
context-application
代替context-activity
- Activity中尽量不要使用非静态内部类,可以使用静态内部类和
WeakReference
代替。
检测
静态检测
静态检测主要是检测资源未关闭的情况,Eclipse和Android Studio都可以检测出IO或者Socket未关闭的情况,然后在finally中关闭即可。
参考资料
- Avoiding memory leaks
- Memory Analysis for Android Applications
- memory_management_for_android_apps
- Google IO:Android内存管理主题演讲记录
- Android内存泄漏分析及调试
0 0
- Android 内存泄露
- android内存泄露 mat
- 预防Android内存泄露
- 预防Android内存泄露
- 预防Android内存泄露
- Android 避免内存泄露
- Android内存泄露分析
- Android内存泄露
- 避免Android内存泄露
- android 内存泄露
- Android 内存泄露测试
- 避免Android内存泄露
- android 内存泄露调试
- 避免Android内存泄露
- android内存泄露优化
- android 内存泄露 小结
- android内存泄露
- Android内存泄露
- 折腾笔记:架设OpenConnect Server给iPhone提供更顺畅的网络生活
- 关于双向链表的相关一系列操作(作为备忘)
- LeetCode(130) Surrounded Regions
- 欢迎使用CSDN-markdown编辑器
- C语言结构体学习系列之(一)
- android内存泄露
- NOIP2011 观光公交(贪心)
- js中三种时间循环的方法
- 关于进栈与出栈(作为备忘)
- Lazy懒加载(延迟加载)UITableView
- css样式规范
- 简单的c语言
- 简单群聊系统
- 关于进队与出队(作为备忘)