练习Sample跑起来 | 唯鹿同学的练习手记 第1辑
下载APP
关闭
渠道合作
推荐作者
练习Sample跑起来 | 唯鹿同学的练习手记 第1辑
2019-02-28 唯鹿 来自北京
《Android开发高手课》
课程介绍
讲述:冯永吉
时长00:46大小724.25K
你好,我是张绍文,今天我要跟你分享唯鹿同学完成专栏课后练习作业的“手记”。专栏承诺会为坚持完成练习作业的同学送出 GMTC 大会门票,唯鹿同学通过自己的努力和坚持,为自己赢得了 GMTC 大会的门票。
如果你还没开始练习,我强烈建议你花一些时间在练习上,因为每个练习的 Sample 都是我和学习委员花费很多精力精心准备的,为的是让你在学习完后可以有机会上手实践,帮你尽快消化专栏里的知识并为自己所用。
大家好,我是唯鹿,来自西安,从事 Android 开发也有近 5 年的时间了,目前在做智慧社区方面的业务。我自己坚持写博客已经有三年多的时间了,希望分享自己在工作、学习中的收获。
先说说我学习专栏的方法,专栏更新当天我就会去学习,但是难度真的不小。我对自己的要求并不是看一遍就要搞明白,而是遇见不懂的地方立马查阅资料,要做到大体了解整篇内容。之后在周末的时候我会集中去做 Sample 练习,一边复习本周发布的内容,一边用写博客的方式记录练习的结果。
后面我计划专栏结束后再多看、多练习几遍,不断查漏补缺。说真的,我很喜欢《Android 开发高手课》的难度,让我在完成练习作业时有种翻越高山的快感。最后,希望同学们一起坚持,享受翻越高山带来的成就感。
最近在学习张绍文老师的《Android 开发高手课》。课后作业可不是一般的难,最近几天抽空练习了一下,结合老师给的步骤和其他同学的经验,完成了前 5 课的内容。
我整理总结了一下,分享出来,希望可以帮到一起学习的同学(当然希望大家尽量靠自己解决问题)。
例子里集成了 Breakpad 来获取发生 Native Crash 时候的系统信息和线程堆栈信息。通过一个简单的 Native 崩溃捕获过程,完成 minidump 文件的生成和解析,在实践中加深对 Breakpad 工作机制的认识。
直接运行项目,按照 README.md 的步骤操作就行。
中间有个问题,老师提供的 minidump_stackwalker 工具在 macOS 10.14 以上无法成功执行,因为没有 libstdc++.6.dylib 库,所以我就下载 Breakpad 源码重新编译了一遍。
使用 minidump_stackwalker 工具来根据 minidump 文件生成堆栈跟踪 log,得到的 crashLog.txt 文件如下:
下来是符号解析,可以使用 NDK 中提供的addr2line来根据地址进行一个符号反解的过程,该工具在$NDK_HOME/toolchains/arm-linux-androideabi-4.9/prebuilt/darwin-x86_64/bin/arm-linux-androideabi-addr2line。
注意:此处要注意一下平台,如果是 ARM 64 位的 so,解析是需要使用 aarch64-linux-android-4.9 下的工具链。
因为我的是 ARM 64 位的 so。所以使用 aarch64-linux-android-4.9,libcrash-lib.so 在app/build/intermediates/cmake/debug/obj/arm64-v8a下,0x600为错误位置符号。
输出结果如下:
可以看到输出结果与下图错误位置一致(第 10 行)。
该例子主要演示了如何通过关闭 FinalizerWatchdogDaemon 来减少 TimeoutException 的触发。
项目使用了 Inline Hook 来拦截内存对象分配时候的 RecordAllocation 函数,通过拦截该接口可以快速获取到当时分配对象的类名和分配的内存大小。
在初始化的时候我们设置了一个分配对象数量的最大值,如果从 start 开始对象分配数量超过最大值就会触发内存 dump,然后清空 alloc 对象列表,重新计算。该功能和 Android Studio 里的 Allocation Tracker 类似,只不过可以在代码级别更细粒度的进行控制。可以精确到方法级别。
项目直接跑起来后,点击开始记录,然后点击 5 次生成 1000 对象按钮。生成对象代码如下:
因为代码从点击开始记录开始,触发到 5000 的数据就 dump 到文件中,点击 5 次后就会在sdcard/crashDump下生成一个时间戳命名的文件。项目根目录下调用命令:
然后就可以在 dump_log.txt 中看到解析出来的数据:
我们用 Android Profiler 查找一个 Message 对象对比一下,一模一样。
简单看一下 Hook 代码:
使用了 Inline Hook 方案 Substrate 来拦截内存对象分配时候 libart.so 的 RecordAllocation 函数。首先如果我们要 hook 一个函数,需要知道这个函数的地址。我们也看到了代码中这个地址判断了四种不同系统。这里有一个网页版的解析工具可以快速获取。下面以 8.0 为例。
我在 8.0 的源码中找到了对应的方法:
7.0 方法就明显不同:
我也同时参看了 9.0 的代码,发现没有变化,所以我的测试机是 9.0 的也没有问题。
Hook 新内存对象分配处理代码:
通过分析内存文件 hprof 快速判断内存中是否存在重复的图片,并且将这些重复图片的 PNG、堆栈等信息输出。
首先是获取我们需要分析的 hprof 文件,我们加载两张相同的图片:
生成 hprof 文件
最终的输出结果:
我们用 Studio 打开 hprof 文件对比一下:
我已经将上面的代码打成 JAR 包,可以直接调用:
因为了解 Linux 不多,所以看这个有点懵逼。好在课代表孙鹏飞同学解答了相关问题,看懂了上面信息,同时学习到了一些 Linux 知识。
上述代码就是导致的问题罪魁祸首,这种密集 I/O 操作集中在 SingleThread 线程中处理,导致发生了 3094 次 faults、36% kernel,完全没有很好利用到 8 核 CPU。
最后,通过检测 CPU 的使用率,可以更好地避免卡顿现象,防止 ANR 的发生。
前前后后用了两三天的时间,远远没有当初想的顺利,感觉身体被掏空。中间也爬了不少坑,虽然没有太深入实现代码,但是中间的体验过程也是收获不小。所以总不能因为难就放弃了,先做到力所能及的部分,让自己动起来!
参考
分享给需要的人,Ta购买本课程,你将得18元
生成海报并分享
赞 2
提建议
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
上一篇
练习Sample跑起来 | ASM插桩强化练习
下一篇
练习Sample跑起来 | 唯鹿同学的练习手记 第2辑
精选留言(10)
- 戴寅华2019-03-02张老师您好,关于chapter01练习,我想自己手动去编译一下breakpad按照您的教程,不过在clone depot_tools的时候,出现了failed to connect 443,搜索后使用了很多可能的办法,好像都不行,还望您指教,谢谢
作者回复: 被墙了?
1 - CathyChen2019-03-01优秀,要向你学习1
- LD2019-03-01优秀1
- 董尚斌2019-02-28优秀1
- 小虎哥V2019-02-28同学太优秀啦,赞1
- 夏2019-02-28优秀1
- zhuxiaohao2019-02-28同学优秀。1
- GEEK_jahen2022-10-27 来自中国香港模仿ProcessCpuTracker能否找到死循环的线程,死循环线程的特点是什么?
- EchoSomeTH2019-07-21ArrayInstance咋弄出来的?请问?那个HahaHelper能发一个吗?共 2 条评论
- 程序员小跃2019-06-20时间是检验真理的唯一标准,给力给力