Android崩溃优化(崩溃分类、原理分析以及解决)

作为技术人员,我们不应该盲目追求崩溃率这一个数字,应该以用户体验为先,如果强行去掩盖一些问题往往更加适得其反。我们不应该随意使用 try catch 去隐藏真正的问题,要从源头入手,了解崩溃的本质原因,保证后面的运行流程。在解决崩溃的过程,也要做到由点到面,不能只针对这个崩溃去解决,而应该要考虑这一类崩溃怎么解决和预防。(附github项目demo参考项目

一、Android 的两种崩溃

我们都知道,Android 崩溃分为 Java 崩溃和 Native崩溃。

简单来说,Java 崩溃就是在 Java 代码中,出现了未捕获异常,导致程序异常退出。那 Native 崩溃一般都是因为Native代码中访问非法地址或者是地址对齐出现问题,再或者是发生程序主动abort,这些都会产生对应的signal信号,导致程序异常退出。所以,“崩溃”就是程序出现异常,而一个产品的崩溃率,跟我们如何捕获、处理这些异常有比较大的关系。Java 崩溃的捕获比较简单,但是很多同学对于如何捕获Native 崩溃还是一知半解,下面我就重点介绍 Native 崩溃的捕获流程和难点。

1、Native崩溃捕获流程(Native 崩溃机制

(1)编译端。编译 C/C++ 代码时,需要将带符号信息的文件保留下来。

(2)客户端。捕获到崩溃时候,将收集到尽可能多的有用信息写入日志文件,然后选择合适的时机上传到服务器。

(3)服务端,读取客户端上报的日志文件,寻找适合的符号文件,生成可读的C/C++调用栈。

2、Native崩溃捕获的难点

Chromium 的Breakpad是目前 Native崩溃捕获中最成熟的方案,所以核心就是保证客户端在各种极端情况下依然可以生成崩溃日志,因为崩溃时,程序处于不安全状态,很可能发生二次崩溃,那么生成崩溃日志主要一些棘手情况:

情况一:文件句柄泄露,导致创建文件日志失败怎么办?应对方式:我们需要提前申请文件句柄fd预留,防止出现这种情况。

情况二:因为栈溢出了导致日志生成失败怎么办?应对方式:为了防止栈溢出导致进程没有空间创建调用栈执行处理函数,我们通常会使用常见的 signalstack。在一些特殊情况,我们可能还需要直接替换当前栈,所以这里也需要在堆中预留部分空间。

情况三:整个堆的内存都耗尽了导致日志生成失败,怎么办?应对方式:这个时候我们无法安全地分配内存,也不敢使用 stl 或者 libc 的函数,因为它们内部实现会分配堆内存。这个时候如果继续分配内存,会导致出现堆破坏或者二次崩溃的情况。Breakpad 做的比较彻底,重新封装了Linux Syscall Supportÿ

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值