Comments (15)
楼上总结的不错,想纠正一点:2. ListView 的 Adapter 中没有使用缓存的 ConvertView。因为前两天刚看了ListView源码,ConvertView其实是滑出屏幕的View的缓存,不使用ConvertView会频繁创建新的View对象,只会造成内存溢出,而不是内存泄漏。这个问题我们首先要明白内存泄漏的真正原因:A对象引用B对象,但是A对象的生命周期比B对象的生命周期长的多,B生命周期到了还在被A引用,导致B对象不能回收,从而引起内存泄漏
from android-daily-interview.
1、内存泄漏的根本原因在于生命周期长的对象持有了生命周期短的对象的引用
2、常见场景
(1)资源对象没关闭造成的内存泄漏(如: Cursor、File等)
(2)全局集合类强引用没清理造成的内存泄漏(特别是 static 修饰的集合)
(3)接收器、监听器注册没取消造成的内存泄漏,如广播,eventsbus
(4)Activity 的 Context 造成的泄漏,可以使用 ApplicationContext
(5)单例中的static成员间接或直接持有了activity的引用
(6)非静态内部类持有父类的引用,如非静态handler持有activity的引用
3、如何避免内存泄漏
(1)编码规范上:
①资源对象用完一定要关闭,最好加finally
②静态集合对象用完要清理
③接收器、监听器使用时候注册和取消成对出现
④context使用注意生命周期,如果是静态类引用直接用ApplicationContext
⑤使用静态内部类
⑥结合业务场景,设置软引用,弱引用,确保对象可以在合适的时机回收
(2)建设内存监控体系
线下监控:
①使用ArtHook检测图片尺寸是否超出imageview自身宽高的2倍
②编码阶段Memery Profile看app的内存使用情况,是否存在内存抖动,内存泄漏,结合Mat分析内存泄漏
线上监控:
①上报app使用期间待机内存、重点模块内存、OOM率
②上报整体及重点模块的GC次数,GC时间
③使用LeakCannery自动化内存泄漏分析
总结:
上线前重点在于线下监控,把问题在上线前解决;上线后运营阶段重点做线上监控,结合一定的预警策略及时处理
4、真的出现低内存,设置一个兜底策略
低内存状态回调,根据不同的内存等级做一些事情,比如在最严重的等级清空所有的bitmap,关掉所有界面,直接强制把app跳转到主界面,相当于app重新启动了一次一样,这样就避免了系统Kill应用进程,与其让系统kill进程还不如浪费一些用户体验,自己主动回收内存
from android-daily-interview.
- 资源对象没关闭造成的内存泄漏(如:
Cursor
、File
等) ListView
的Adapter
中没有使用缓存的ConvertView
Bitmap
对象不在使用时调用recycle()释放内存- 集合中对象没清理造成的内存泄漏(特别是
static
修饰的集合) - 接收器、监听器注册没取消造成的内存泄漏
Activity
的Context
造成的泄漏,可以使用ApplicationContext
Handler
造成的内存泄漏问题(一般由于Handler
生命周期比其外部类的生命周期长引起的)
from android-daily-interview.
纠正一点,bitmap早就不需要手动调用recycle了,可以看看这篇文章:https://www.jianshu.com/p/76bbdc4bcad8
from android-daily-interview.
需要被释放的资源没有被及时释放 就会造成内存泄漏 。
可能的场景有好些种 ,大多都是因为异步操作造成的 ,或者生命周期长的持有了生命周期短的引用。
1.handler 消息
2.非静态内部类
3.异步操作 还有AsyncTask 等
4.静态类持有非静态类 比如工具类莫名持有context
5.资源对象未关闭(File流 Cursor )
6.注册监听 未及时注销
from android-daily-interview.
总的来说就是生命周期长的对象持有了生命周期短的对象,导致生命周期短的对象在回收时导致对象无法释放,从而导致内存泄漏。
from android-daily-interview.
Android中常见的:资源对象未关闭、全局集合类强引用、广播接收器或是EventBus等未反注册、Context的错误使用以及Context与单例的问题、非静态内部类与Handler的问题。
from android-daily-interview.
内存泄漏造成的原因
无非是生命周期长的对象持有生命周期短的对象的引用,造成生命周期短的对象使用完之后无法释放内存;
内存泄漏出现的场景:
非静态内部类(非静态内部类默认持有外部类的引用,例如Handler:消息队列里的消息持有handler的引用,handler作为内部类持有外部类的引用),注册未解绑(例如EventBUS),资源未关闭未释放(webview、Bitmap未释放),静态变量(例如单例模式),集合容器(通常把一些对象的引用加入到集合容器中)
解决办法:
使用静态内部类或者把内部类独立出来,如果需要context,使用applicationcontext,如果需要引用外部类的变量,使用弱引用的方式
from android-daily-interview.
从这个内存泄漏的主题,还可以引出的知识点:
- Java 中的 static 关键字;
- Java 中的 4 种引用(强、软、弱、虚引用);
- Java 内部类的使用;
from android-daily-interview.
1.非静态内部类(非静态内部类默认持有外部类的引用,例如Handler:消息队列里的消息持有handler的引用,handler作为内部类持有外部类的引用)
2.注册未解绑(例如EventBUS),
3.资源未关闭未释放(webview、Bitmap未释放)、
4.静态变量(例如单例模式),
5.集合容器(通常把一些对象的引用加入到集合容器中)
from android-daily-interview.
1.资源未关闭释放(如数据库操作未关流)
2.注册的监听未注销(如广播注册了,没有解绑)
3.非静态内部类持有外部类的引用(如Handler)
4.静态变量(如单例)
5.集合容器没有清空(如一些对象引用放到集合容器,ThreadLocal变量)
from android-daily-interview.
非静态内部类对外部有一个引用
context被单例持有
context被静态变量持有
bitmap没回收
bus没反注册
资源对象没关闭(cursor)
总而言之就是 持有了 本该没有继续使用的对象,导致他无法释放, gcroot
检测方式有以下几种
1.leakCanary
原理是, 用activityfragmentlifecyclercallback 去监听acvivity 或者 fragment 的ondestory时机
并且弱引用持有他们, 把他们的弱引用关联到引用队列
引用队列的作用是, 当 和他关联的引用发生变化会被添加进这个引用队列
于是 当activity 或 fragment ondestory的时候 会去检测 这些弱引用是否被回收,如果没有则触发gc(此时肯定没有leak 肯定会被回收).如果弱引用还存在 则证明leak,把当前的内存信息dump出来,用square的另外一个第三方库 haha 来进行内存分析
2. 使用android studio 自带的profiler 进行内存分析,在退出当前activity的时候,看下时间线,当前的actvitiy的对象引用数有几个,如果不为0则 手动发起gc 看看是否 有减少,如果没有,则把当前内存快照dump出来,然后用 mat进行分析
from android-daily-interview.
都忽略了内存泄漏的定义,应该是当GC来临时,本该释放回收的对象,因为被其他对象持有,导致无法释放;注意和内存溢出的区别
from android-daily-interview.
这个问题应该从内存抖动,内存泄露,内存溢出三个纬度讲解,再结合线上和线下的监控手段
from android-daily-interview.
内存泄漏原因
生命周期长的对象使用了生命周期短的对象的引用,造成生命周期短的对象使用完之后内存无法及时释放
比如说
数据库和文件操作完没有关闭
注册的事件没有注销掉
bitmap没有关闭
单例中的start成员使用了activity的引用
context不合理的使用
from android-daily-interview.
Related Issues (20)
- 2020-01-14:为什么协程比线程要轻量? HOT 19
- 2020-01-15:你了解过哪些Android屏幕适配方面的技巧? HOT 2
- 2020-01-16:为什么ViewPager嵌套ViewPager,内部的ViewPager滚动没有被拦截? HOT 3
- 2020-01-17:说说你未来的职业规划是怎样的? HOT 23
- 2020-03-02:Java中为什么会出现Atomic类?试分析它的原理和缺点? HOT 1
- 2020-03-03:说说ThreadLocal的使用场景?与Synchronized相比有什么特性? HOT 6
- 2020-03-04:试从源码角度分析Handler的post和sendMessage方法的区别和应用场景? HOT 6
- 2020-03-06:JMM是什么?它存在哪些问题?该如何解决? HOT 3
- 2020-03-09:谈谈Https的加密过程? HOT 3
- 113 Android Interview Questions Answered (ENGLISH) HOT 1
- 当点击的时候,会先调用顶级viewgroup的dispatchTouchEvent,如果顶级的viewgroup拦截了此事件(onInterceptTouchEvent返回true),则此事件序列由顶级viewgroup处理。如果顶级viewgroup设置setOnTouchListener,则会回调接口中的onTouch,此时顶级的viewgroup中的onTouchEvent不再回调,如果不设置setOnTouchListener则onTouchEvent会回调。如果顶级viewgroup设置setOnClickListener,则会回调接口中的onClick。如果顶级viewgroup不拦截事件,事件就会向下传递给他的子view,然后子view就会调用它的dispatchTouchEvent方法。
- 2020-9-29:Java内存模型 HOT 1
- 2020-9-29:java中的锁机制
- app 进程分为哪几种?在项目中的实际应用?
- 学习
- View inflation
- 群被封了 HOT 2
- Android HOT 2
- 为啥不搞了 HOT 3
- 2024年了, Android行情怎么样了 HOT 5
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
D3
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
-
Recommend Topics
-
javascript
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
-
web
Some thing interesting about web. New door for the world.
-
server
A server is a program made to process requests and deliver data to clients.
-
Machine learning
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from android-daily-interview.