ANR处理方法:
使用 FileObserver 监听 /data/anr/traces.txt 的变化。非常不幸的是,很多高版本的 ROM,已经没有读取这个文件的权限了。这个时候你可能只能思考其他路径,海外可以使用 Google Play 服务,而国内微信利用Hardcoder框架(HC 框架是一套独立于安卓系统实现的通信框架,它让 App 和厂商 ROM 能够实时“对话”了,目标就是充分调度系统资源来提升 App 的运行速度和画质,切实提高大家的手机使用体验)向厂商获取了更大的权限。也可以将手机 ROOT 掉,然后取得 traces.txt 文件。

1.3 应用退出

除了常见的崩溃,还有一些会导致应用异常退出的情况,例如:

  • 主动自杀。Process.killProcess()、exit() 等
  • 崩溃。出现了 Java 或 Native 崩溃
  • 系统重启。系统出现异常、断电、用户主动重启等,我们可以通过比较应用开机运行时间是否比之前记录的值更小
  • 被系统杀死。被 low memory killer 杀掉、从系统的任务管理器中划掉等
  • ANR

我们可以在应用启动的时候设定一个标志,在主动自杀或崩溃后更新标志,这样下次启动时通过检测这个标志就能确认运行期间是否发生过异常退出。对应上面的五种退出场景,我们排除掉主动自杀和崩溃(崩溃会单独的统计)这两种场景,希望可以监控到剩下三种的异常退出,理论上这个异常捕获机制是可以达到 100% 覆盖的。

通过这个异常退出的检测,可以反映如 ANR、low memory killer、系统强杀、死机、断电等其他无法正常捕获到的问题。当然异常率会存在一些误报,比如用户从系统的任务管理器中划掉应用。对于线上的大数据来说,还是可以帮助我们发现代码中的一些隐藏问题。

根据应用的前后台状态,我们可以把异常退出分为前台异常退出和后台异常退出。“被系统杀死” 是后台异常退出的主要原因,当然我们会更关注前台的异常退出的情况,这会跟 ANR、OOM 等异常情况有更大的关联。

二、崩溃处理

我们每天工作也会遇到各种各样的疑难问题,“崩溃”就是其中比较常见的一种问题。解决问题跟破案一样需要经验,我们分析的问题越多越熟练,定位问题就会越快越准。当然这里也有很多套路,比如对于 “案发现场” 我们应该留意哪些信息?怎样找到更多的 “证人” 和 “线索” ? “侦查案件” 的一般流程是什么?对不同类型的 “案件” 分别应该使用什么样的调查方式?

要相信 “真相永远只有一个”,崩溃也并不可怕。

2.1 崩溃现场

崩溃现场是我们的“第一案发现场”,它保留着很多有价值的线索。现在可以挖掘到的信息越多,下一步分析的方向就越清晰,而不是去靠盲目猜测。

崩溃信息

从崩溃的基本信息,我们可以对崩溃有初步的判断。进程名、线程名。崩溃的进程是前台进程还是后台进程,崩溃是不是发生在 UI 线程。

崩溃堆栈和类型。崩溃是属于 Java 崩溃、Native 崩溃,还是 ANR,对于不同类型的崩溃关注的点也不太一样。特别需要看崩溃堆栈的栈顶,看具体崩溃在系统的代码,还是 APP 代码里面。

关键字:FATAL

FATAL EXCEPTION: main
Process: com.cchip.csmart, PID: 27456
java.lang.NullPointerException: Attempt to invoke virtual method ‘void android.widget.TextView.setText(int)’ on a null object reference
at com.cchip.alicsmart.activity.SplashActivity1.handleMessage(SplashActivity.java:67)atandroid.os.Handler.dispatchMessage(Handler.java:102)atandroid.os.Looper.loop(Looper.java:179)atandroid.app.ActivityThread.main(ActivityThread.java:5672)atjava.lang.reflect.Method.invoke(NativeMethod)atcom.android.internal.os.ZygoteInit1.handleMessage(SplashActivity.java:67) at android.os.Handler.dispatchMessage(Handler.java:102) at android.os.Looper.loop(Looper.java:179) at android.app.ActivityThread.main(ActivityThread.java:5672) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.ZygoteInit1.handleMessage(SplashActivity.java:67)atandroid.os.Handler.dispatchMessage(Handler.java:102)atandroid.os.Looper.loop(Looper.java:179)atandroid.app.ActivityThread.main(ActivityThread.java:5672)atjava.lang.reflect.Method.invoke(NativeMethod)atcom.android.internal.os.ZygoteInitMethodAndArgsCaller.run(ZygoteInit.java:784)
at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:674)

系统信息

系统的信息有时候会带有一些关键的线索,对我们解决问题有非常大的帮助。

Logcat。这里包括应用、系统的运行日志。由于系统权限问题,获取到的 Logcat 可能只包含与当前 APP 相关的。其中系统的 event logcat 会记录 APP 运行的一些基本情况,记录在文件 /system/etc/event-log-tags 中。

//system logcat:
10-25 17:13:47.788 21430 21430 D dalvikvm: Trying to load lib …

//event logcat:
10-25 17:13:47.788 21430 21430 I am_on_resume_called: 生命周期
10-25 17:13:47.788 21430 21430 I am_low_memory: 系统内存不足
10-25 17:13:47.788 21430 21430 I am_destroy_activity: 销毁 Activty
10-25 17:13:47.888 21430 21430 I am_anr: ANR 以及原因
10-25 17:13:47.888 21430 21430 I am_kill: APP 被杀以及原因

机型、系统、厂商、CPU、ABI、Linux 版本等。通过采集多达几十个维度,这对寻找共性问题会很有帮助。

内存信息

OOM、ANR、虚拟内存耗尽等,很多崩溃都跟内存有直接关系。如果把用户的手机内存分为“2GB 以下”和“2GB 以上”两个区,就会发现“2GB 以下”用户的崩溃率是“2GB 以上”用户的几倍。

系统剩余内存。关于系统内存状态,可以直接读取文件 /proc/meminfo。当系统可用内存很小(低于 MemTotal 的 10%)时,OOM、大量 GC、系统频繁自杀拉起等问题都非常容易出现。

应用使用内存。包括 Java 内存、RSS(Resident Set Size)、PSS(Proportional Set Size),我们可以得出应用本身内存的占用大小和分布。PSS 和 RSS 通过 /proc/self/smap 计算,可以进一步得到例如 apk、dex、so 等更加详细的分类统计。

虚拟内存。虚拟内存可以通过 /proc/self/status 得到,通过 /proc/self/maps 文件可以得到具体的分布情况。有时候我们一般不太重视虚拟内存,但是很多类似 OOM、tgkill 等问题都是虚拟内存不足导致的。

Name: com.xmamiga.name // 进程名
FDSize: 800 // 当前进程申请的文件句柄个数
VmPeak: 3004628 kB // 当前进程的虚拟内存峰值大小
VmSize: 2997032 kB // 当前进程的虚拟内存大小
Threads: 600 // 当前进程包含的线程个数

一般来说,对于 32 位
进程,如果是 32 位的 CPU,虚拟内存达到 3GB 就可能会引起内存申请失败的问题。如果是 64 位的 CPU,虚拟内存一般在 3~4GB 之间。当然如果我们支持 64 位进程,虚拟内存就不会成为问题。Google Play 要求 2019 年 8 月一定要支持 64 位,在国内虽然支持 64 位的设备已经在 90% 以上了,但是商店都不支持区分 CPU 架构类型发布,普及起来需要更长的时间。

资源信息

有的时候会发现应用堆内存和设备内存都非常充足,还是会出现内存分配失败的情况,这跟资源泄漏可能有比较大的关系。

文件句柄 fd。文件句柄的限制可以通过 /proc/self/limits 获得,一般单个进程允许打开的最大文件句柄个数为 1024。但是如果文件句柄超过 800 个就比较危险,需要将所有的 fd 以及对应的文件名输出到日志中,进一步排查是否出现了有文件或者线程的泄漏。

opened files count 812:
0 -> /dev/null
1 -> /dev/log/main4
2 -> /dev/binder
3 -> /data/data/com.xmamiga.sample/files/test.config

线程数。当前线程数大小可以通过上面的 status 文件得到,一个线程可能就占 2MB 的虚拟内存,过多的线程会对虚拟内存和文件句柄带来压力。根据我的经验来说,如果线程数超过 400 个就比较危险。需要将所有的线程 id 以及对应的线程名输出到日志中,进一步排查是否出现了线程相关的问题。

threads count 412:
1820 com.xmamiga.crashsdk
1844 ReferenceQueueD
1869 FinalizerDaemon

JNI。使用 JNI 时,如果不注意很容易出现引用失效、引用爆表等一些崩溃。

应用信息

除了系统,其实我们的应用更懂自己,可以留下很多相关的信息。崩溃场景。崩溃发生在哪个 Activity 或 Fragment,发生在哪个业务中; 关键操作路径,不同于开发过程详细的打点日志,我们可以记录关键的用户操作路径,这对我们复现崩溃会有比较大的帮助。其他自定义信息。不同的应用关心的重点可能不太一样。

2.2 崩溃分析

有了这么多现场信息之后,就可以开始真正的“破案”之旅了。绝大部分的 “案件” 只要肯花功夫,最后都能真相大白。不要畏惧问题,经过耐心和细心地分析,总能敏锐地发现一些异常或关键点,并且还要敢于怀疑和验证。

2.2 崩溃分析

有了这么多现场信息之后,就可以开始真正的“破案”之旅了。绝大部分的 “案件” 只要肯花功夫,最后都能真相大白。不要畏惧问题,经过耐心和细心地分析,总能敏锐地发现一些异常或关键点,并且还要敢于怀疑和验证。

Android-高质量开发之崩溃优化,赶紧学起来相关推荐

  1. Android 高质量开发之崩溃优化

    做了很久的面试专题,不知道对各位需要面试和有跳槽想法的小伙伴有没有帮助,今天收集一篇关于崩溃优化方面的文章,面试方面的收集,后续我还会持续更新如果觉得有用可以点个关注 原文链接:https://www ...

  2. Android 高质量开发之崩溃优化,kotlinnativerust跨端

    一.崩溃 崩溃率是衡量一个应用质量高低的基本指标,那么,该怎样客观地衡量崩溃这个指标,以及又该如何看待和崩溃相关的稳定性.Android 的两种崩溃: Java 崩溃 Native 崩溃 简单来说,J ...

  3. Android 高质量开发之崩溃优化,kotlin匿名内部类

    崩溃率是不是就能完全等价于应用的稳定性呢?答案是肯定不行.处理了崩溃,我们还会经常遇到 ANR(Application Not Responding,程序没有响应)这个问题.出现 ANR 的时候,系统 ...

  4. Android 高质量开发之崩溃优化,kotlin协程跟线程

    1.3 应用退出 除了常见的崩溃,还有一些会导致应用异常退出的情况,例如: 主动自杀.Process.killProcess().exit() 等 崩溃.出现了 Java 或 Native 崩溃 系统 ...

  5. Android 高质量开发之崩溃优化,2020-2021字节跳动Android面试真题解析

    除了常见的崩溃,还有一些会导致应用异常退出的情况,例如: 主动自杀.Process.killProcess().exit() 等 崩溃.出现了 Java 或 Native 崩溃 系统重启.系统出现异常 ...

  6. Android源码-高质量开发库

    借鉴:秀源码http://www.xiufm.com/forum.php?mod=viewthread&tid=14873&highlight=Android%E6%BA%90%E7% ...

  7. android 高质量游戏,你玩过几款?2013年度十大安卓热门游戏大盘点

    转眼又是一年,2013也即将离我们而去,这是手游蓬勃发展的一年,各种类型的佳作不断涌现,给广大玩家带来了许多欢乐,手游已然成为大家生活中不可或缺的调剂品. 每个人都有自己喜爱的游戏,它不一定要有华丽的 ...

  8. 5个高质量PPT模板网站,赶紧马住。

    本期分享5个高质量免费PPT模板网站,建议收藏! 1.菜鸟图库 ppt模板免费下载|ppt背景图片 - 菜鸟图库 菜鸟图库网有非常丰富的免费素材,像设计类.办公类.自媒体类等素材都很丰富.PPT模板种 ...

  9. 被称为“2022大热门”的Android车载系统开发,到底应该怎么学?

    前言: 随着汽车智能化的速度不断加快,车载系统目前已经进入了混战的阶段,国产车载系统纷纷加入布局,很多车企也基于Android车载系统来开发自己的新系统,不过想要打造像安卓一样的汽车生态,还有很大的发 ...

最新文章

  1. 图解 二叉查找树 红黑树
  2. 【学习笔记】JS基础语法一小时通
  3. java 枚举使用例子_Java枚举详解及使用实例(涵盖了所有典型用法)
  4. linux IP、端口连通性测试
  5. 《黑客攻防技术宝典Web实战篇@第2版》读书笔记1:了解Web应用程序
  6. Redis分布锁原理简介和实现过程
  7. kill apache
  8. 普通程序员如何向人工智能方向转型?
  9. hexo添加_hexo 如何给文章添加目录
  10. 揭秘《英雄联盟》的游戏自动化测试
  11. 加载配置文件(xml文件,properties文件)demo
  12. 计算机c盘主要放那些,c盘哪些文件可以删除(电脑C盘文件夹哪些可以删除?)...
  13. matlab凑数求和,excel自动凑数求和 使用规划求解来解决excel自动凑数求和的方法...
  14. python全栈示例_Python全栈之路--Django ORM详解
  15. 易优EyouCMS手机端url路径改为/mobile/方案(非自带m.xxx.com二级域名方案)
  16. 大数据之flink定时器
  17. layaari2-cmd 踩坑记录,解决安装失败问题
  18. Android读取中文文件乱码解决方法
  19. php梯形评论,PHP梯形的上底.下底.高,点击计算面积按钮,输出梯形面积.
  20. 第五章Table(3)

热门文章

  1. markdown绘图插件 ---- mermaid简介
  2. JavaScript 进阶知识 - Ajax篇
  3. 杰奇是否生成html,杰奇1.70如何自定义页面
  4. java 封闭实例_java – 每个内部类都需要一个封闭的实例是真的吗?
  5. 如何将不同情况下的List带到SQL中进行判断操作
  6. python 统计哈姆雷特词汇频率
  7. 微信的新消息一键标为已读.简单的微信脚本,使用autojs编写的安卓自动化脚本
  8. 【开源轶事00】Redis 是亲生的懒汉 Java 庶出终归是庶出
  9. html5这么盒子页面居中,实现盒子居中
  10. npm编译报错You may need an additional loader to handle the result of these loaders