前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Android客户端性能异常类

Android客户端性能异常类

作者头像
Steve Wang
发布2021-12-06 16:31:58
3.9K0
发布2021-12-06 16:31:58
举报
文章被收录于专栏:从流域到海域从流域到海域

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错误解析指令
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2021-07-20 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • Android客户端性能异常类
  • 超时 (Time Out)
  • 崩溃 (Crash)
    • Java崩溃
      • Native崩溃
      领券
      问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档