Android内存优化- 严苛模式StrictMode使用详解
来源:互联网 发布:淘宝文玩店推荐 编辑:程序博客网 时间:2024/06/04 17:42
StrictMode具体能检测什么
严苛模式主要检测两大问题,一个是线程策略,即TreadPolicy,另一个是VM策略,即VmPolicy。
ThreadPolicy线程策略检测
- 线程策略检测的内容有
- 自定义的耗时调用 使用detectCustomSlowCalls()开启
- 磁盘读取操作 使用detectDiskReads()开启
- 磁盘写入操作 使用detectDiskWrites()开启
- 网络操作 使用detectNetwork()开启
VmPolicy虚拟机策略检测(检测内存泄露)
- Activity泄露 使用detectActivityLeaks()开启
- 未关闭的Closable对象泄露 使用detectLeakedClosableObjects()开启
- 泄露的Sqlite对象 使用detectLeakedSqlLiteObjects()开启
- 检测实例数量 使用setClassInstanceLimit()开启
工作原理
其实StrictMode实现原理也比较简单,以IO操作为例,主要是通过在open,read,write,close时进行监控。libcore.io.BlockGuardOs文件就是监控的地方。以open为例,如下进行监控。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
其中onReadFromDisk()方法的实现,代码位于StrictMode.java中。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
常见用法
严格模式的开启可以放在Application或者Activity以及其他组件的onCreate方法。为了更好地分析应用中的问题,建议放在Application的onCreate方法中。
其中,我们只需要在app的开发版本下使用 StrictMode,线上版本避免使用 StrictMode,这里定义了一个布尔值变量DEV_MODE来进行控制。
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
其中Android3.0引入的方法包括detectCustomSlowCalls()和noteSlowCode(),它们都是用来检测应用中执行缓慢代码的或者潜在的缓慢代码。
查看报告结果
严格模式有很多种报告违例的形式,但是想要分析具体违例情况,还是需要查看日志,终端下过滤StrictMode就能得到违例的具体stacktrace信息。
- 1
- 1
- StrictMode从 API 11开始允许开发者自定义一些耗时调用违例,这种自定义适用于自定义的任务执行类中,比如我们有一个进行任务处理的类,为TaskExecutor。
- 1
- 2
- 3
- 4
- 5
- 1
- 2
- 3
- 4
- 5
先需要跟踪每个任务的耗时情况,如果大于500毫秒需要提示给开发者,noteSlowCall就可以实现这个功能,如下修改代码
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
执行一个耗时2000毫秒的任务
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
得到的违例日志,注意其中~duration=20 ms并非耗时任务的执行时间,而我们的自定义信息msg=slowCall cost=2000才包含了真正的耗时。
penaltyDeath(),当触发违规条件时,直接Crash掉当前应用程序。
penaltyDeathOnNetwork(),当触发网络违规时,Crash掉当前应用程序。
penaltyDialog(),触发违规时,显示对违规信息对话框。
penaltyFlashScreen(),会造成屏幕闪烁,不过一般的设备可能没有这个功能。
penaltyDropBox(),将违规信息记录到 dropbox 系统日志目录中(/data/system/dropbox),你可以通过如下命令进行插件:
- 1
- 1
permitCustomSlowCalls()、permitDiskReads ()、permitDiskWrites()、permitNetwork: 如果你想关闭某一项检测,可以使用对应的permit*方法。
VMPolicy 详解
StrictMode.VmPolicy.Builder 主要方法如下
detectActivityLeaks() 用户检查 Activity 的内存泄露情况
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
我们反复旋转屏幕就会输出提示信息(重点在 instances=2; limit=1 这一行)
这时因为,我们在Activity中创建了一个Thread匿名内部类,而匿名内部类隐式持有外部类的引用。而每次旋转屏幕是,Android会新创建一个Activity,而原来的Activity实例又被我们启动的匿名内部类线程持有,所以不会释放,从日志上看,当先系统中该Activty有4个实例,而限制是只能创建1各实例。我们不断翻转屏幕,instances 的个数还会持续增加。
detectLeakedSqlLiteObjects() 和
detectLeakedClosableObjects()的用法类似,只不过是用来检查 SQLiteCursor 或者 其他 SQLite
对象是否被正确关闭detectLeakedRegistrationObjects() 用来检查 BroadcastReceiver 或者
ServiceConnection 注册类对象是否被正确释放setClassInstanceLimit(),设置某个类的同时处于内存中的实例上限,可以协助检查内存泄露
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
- 11
- 12
- 13
- 14
- 15
- 16
- 17
- 18
- 19
- 20
- 21
- 22
- 23
- 24
- 25
- 26
- 27
- 28
运行后触发警告如下
其他操作
除了通过日志查看之外,我们也可以在开发者选项中开启严格模式,开启之后,如果主线程中有执行时间长的操作,屏幕则会闪烁,这是一个更加直接的方法。
注意事项
- 只在开发阶段启用StrictMode,发布应用或者release版本一定要禁用它。
- 严格模式无法监控JNI中的磁盘IO和网络请求。
- 应用中并非需要解决全部的违例情况,比如有些IO操作必须在主线程中进行。
- Android内存优化- 严苛模式StrictMode使用详解
- Android严苛模式StrictMode使用详解
- Android严苛模式StrictMode使用详解
- Android严苛模式StrictMode使用详解
- Android严苛模式StrictMode使用详解
- Android严苛模式StrictMode使用详解
- android StrictMode(严苛模式)详解
- Android性能优化-StrictMode(严苛模式)
- Android 严苛模式(StrictMode)详解
- Android StrictMode 严苛模式
- Android- 严苛模式(StrictMode)
- Android严苛模式介绍(StrictMode)
- Android:StrictMode(严苛模式)
- Android的StrictMode(严苛模式)
- Android之严苛模式(StrictMode)
- Android探索之旅 | StrictMode严苛模式
- android 严苛模式(StrictMode)——StrictMode.setThreadPolicy
- android 严苛模式(StrictMode)——StrictMode.setThreadPolicy
- // android imageloader 的使用
- 日往月来
- JPA学习笔记-JPA进阶
- web上传文件,并获取返回数据
- 进程间通信的竞争条件详解
- Android内存优化- 严苛模式StrictMode使用详解
- get请求参数乱码解决
- 安装测试点云配准4PCS算法
- Freeline
- ipa提取png图片,windows下显示黑色
- HTML定义ESCPOS热敏打打印模板,打印小票
- 机器学习岗面试点滴聚集
- Java在不同环境下获取当前路径的方法
- HTML 5 视频直播一站式扫盲