Android-高质量开发之崩溃优化,薪资翻倍【附源码】_mb612646278a90a

 ###### 系统信息  系统的信息有时候会带有一些关键的线索,对我们解决问题有非常大的帮助。  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 崩溃分析 有了这么多现场信息之后,就可以开始真正的“破案”之旅了。绝大部分的 “案件” 只要肯花功夫,最后都能真相大白。不要畏惧问题,经过耐心和细心地分析,总能敏锐地发现一些异常或关键点,并且还要敢于怀疑和验证。  ###### 第一步:确定重点  确认和分析重点,关键在于终过日志中找到重要的信息,对问题有一个大致判断。一般来说,我建议在确定重点这一步可以关注以下几点。    - 确认严重程度。解决崩溃也要看性价比,我们优先解决 Top 崩溃或者对业务有重大影响,例如主要功能的崩溃。不要花几天去解决了一个边角的崩溃,有可能下个版本就把功能删除了。 - 崩溃基本信息。确定崩溃的类型以及异常描述,对崩溃有大致的判断。 一般来说,大部分的简单崩溃经过这一步已经可以得到结论。  Java 崩溃。Java 崩溃类型比较明显,比如 NullPointerException 是空指针,OutOfMemoryError 是资源不足,这个时候需要去进一步查看日志中的 “内存信息”和“资源信息”。  Native 崩溃。需要观察 signal、code、fault addr 等内容,以及崩溃时 Java 的堆栈。关于各 signal 含义的介绍,你可以查看崩溃信号介绍。比较常见的是有 SIGSEGV 和 SIGABRT,前者一般是由于空指针、非法指针造成,后者主要因为 ANR 和调用 abort() 退出所导致。  ANR。先看看主线程的堆栈,是否是因为锁等待导致。接着看看 ANR 日志中 iowait、CPU、GC、system server 等信息,进一步确定是 I/O 问题,或是 CPU 竞争问题,还是由于大量 GC 导致卡死。  ###### 第二步:查找共性  如果使用了上面的方法还是不能有效定位问题,我们可以尝试查找这类崩溃有没有什么共性。找到了共性,也就可以进一步找到差异,离解决问题也就更进一步。  机型、系统、ROM、厂商、ABI,这些采集到的系统信息都可以作为维度聚合,共性问题例如是不是只出现在 x86 的手机,是不是只有三星这款机型,是不是只在 Android 8.0 的系统上。应用信息也可以作为维度来聚合,比如正在打开的链接、正在播放的视频、国家、地区等。  找到了共性,可以对你下一步复现问题有更明确的指引。  ###### 第三步:尝试复现  ### 更多Android高级工程师进阶学习资料  **进阶学习视频** ![](https://s2.51cto.com/images/20210917/1631863038333537.jpg)  附上:我们之前因为秋招收集的二十套一二线互联网公司Android面试真题(含BAT、小米、华为、美团、滴滴)和我自己整理Android复习笔记(包含Android基础知识点、Android扩展知识点、Android源码解析、设计模式汇总、Gradle知识点、常见算法题汇总。)  ![](https://s2.51cto.com/images/20210917/1631863039878623.jpg)  * ##### **[CodeChina开源项目:《Android学习笔记总结+移动架构视频+大厂面试真题+项目实战源码》](https://ali1024.coding.net/public/P7/Android/git)**    **里面包含不同方向的自学编程路线、面试题集合/面经、及系列技术文章等,资源持续更新中…**

本站由小牛团队全力维护,小牛十年了,大家已经步入中年 。本站源码全部经过团队成员测试并调试,价格可能比其它网站略贵几元钱,不解释!
小牛资源 » Android-高质量开发之崩溃优化,薪资翻倍【附源码】_mb612646278a90a

发表评论

全站资源亲测可用,价格略高几元,不解释

立即查看 了解详情