Android客户端性能异常类

Android客户端性能异常类

在这里插入图片描述

影响app体验的通用类问题可以分为两大类:超时和崩溃。

超时 (Time Out)

没有在用户的预期内及时的响应用户的请求和交互。

分为:较轻的影响是UI的卡顿掉帧;
比较大的影响是ANR(Application Not Responding):能恢复的ANR;不能恢复的ANR-永久性卡死问题。

超时的原因:

  • UI线程中block的操作;
  • IO/数据库/网络耗时操作;
  • 复杂不合理的布局;
  • overdraw的过度绘制;
  • 内存使用异常导致的卡顿,例如内存抖动或泄露等导致GC的次数增多,消耗在GC的时间长,CPU绘制时间会短;
  • 不合理的异步(会导致CPU占用互斥资源);

崩溃 (Crash)

在某些场景下,满足的条件未满足或者需要的资源没有拿到,出现的未预期的运行时异常。

类型破坏性解决难度
ANR
Java Crash
Native Crash
Java崩溃

可分为三大类:check异常,runtime异常,错误;
这里的crash都会抓到完整的调用栈信息,且大部分和业务侧的逻辑使用相关

  • checked异常:由编程与环境互动造成程序在运行时出错,编译时异常
  • Error类:通常是指Java的内部错误以及如资源耗尽的错误
  • runtime异常:运行时异常

常见原因:
在这里插入图片描述

Native崩溃

主动类:运行时框架代码或业务代码发现的状态异常,代码运行过程中主动触发;这类异常在预期范围内,通过此类方法暴露问题。例如:资源不足,内存超过阈值等。

被动类:在运行时执行一些指令或者访问某些内存地址被动触发的;不在预期范围内;比如:野指针,多线程操作文件没有同步保护等等。

Native崩溃使用信号(singal)机制返回信息:
在这里插入图片描述

Android native崩溃产生常见信号大致有以下几类:

  • SIGABRT
  • SIGSTKFLT
  • SIGTARP
  • SIGSEGV
  • SIGBUS
  • SIGILL
SIGABRT

SIG是信号名的通用前缀。ABRT是abort program的缩写;由调用abort函数产生,进程非正常退出。当用户态的 Native 代码在运行过程中发现了某些状态异常,就会给自己(线程)发送信号触发自杀流程。
常见问题有:

  1. 异常流程:当系统因内存不足无法分配buffer,代码就选择了调用宏函数,自杀了

  2. 虚拟内存泄漏:32位APP的地址空间只有4GB,因此程序运行过程中内存用的多了容易引起OOM。64位APP地址空间几乎无限大,基本不存在OOM的问题;
    通过获取崩溃时的虚拟内存大小,就知道是否有内存泄漏;

    内存泄漏关键字
    另外,因为是SIGABRT类型,虚拟内存泄漏也有常见的Abort Message关键字:

    • Out of memory
    • Failed to map PBO
    • failed to allocate TLS
  3. 虚拟机异常

    • Thread suspend timeout(线程挂起时间过长)
    • local reference table overflow (本地引用表溢出)
    • java.lang.OutOfMemoryError
    • 文件描述符泄漏
    • 堆内存破坏
SIGTKFLT

协处理器的栈异常。这类异常是dvm虚拟机特有的。dvm虚拟机在GC或者打印trace文件时会suspend所有线程,如果有suspend失败的线程,就会给这个线程发送SIGSTKFLT信号。

SIGTRAP

SIGTRAP是通过汇编指令bkpt触发CPU的预取指异常,并在内核态的预取指异常处理函数中,给当前线程发送SIGTRAP信号。

汇编指令bkpt(break point的缩写),用于产生软件断点中断,以便软件调试时使用。

SIGSEGV

非法内存操作,与下面的SIGBUS不同,是对合法地址的非法访问,比如访问没有读权限的内存向没有写权限的地址写数据等
SIGSEGV类错误出现在CPU的虚拟地址转换物理地址的过程,分两种不同情况。

  • SEGV_MAPERR:当前执行的指令访问的内存地址未映射到当前进程地址空间
  • SEGV_ACCERR:当前执行的指令访问的内存地址无访问权限(读、写、执行)

SEGV_MAPERR:

  • 字符串溢出:寄存器中不够存储字符串长度
  • 空对象:底层某个对象null了
  • PC跑飞:一般是程序(PC寄存器)跑飞或者栈(SP寄存器)被破坏
SIGBUS

非法地址,包括内存地址对齐出错,比如访问一个4字节的整数, 但其地址不是4的倍数。细分为:

  • BUS_ADRALN:当前执行的指令访问的内存地址不符合指令的对齐规范
    • 这类异常通常是内存踩踏导致的偶现的随机问题,概率极小
  • BUS_ADRERR:当前执行的指令访问的文件映射地址的缺页异常错误
    • 这类异常和文件的读写相关
SIGILL

当前执行的指令是CPU无法识别的非法指令时,会触发SIGILL信号。根据异常指令的来源分三种情况。

  • udf指令:此指令 arm cpu无法识别
  • 指令被破坏:生成指令时(ROM or RAM的BIt位反转)出错,导致RAM或者ROM中的指令异常;属于硬件出错
  • 指令集错误:CPU错误解析指令
  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值