ANR类型

95 阅读3分钟

未命名-4.png

应用侧

  1. 主线程耗时

    • Java Call:主线程执行耗时操作,例如复杂的计算、数据库查询、文件 I/O 等,导致 UI 线程卡顿,触发 ANR。
    • Native Call:调用 JNI 代码时,C/C++ 代码执行时间过长,也会导致主线程卡死,例如长时间的 I/O 或复杂的算法计算。
  2. 线程状态问题

    • Waiting:线程处于等待状态,等待某个锁或者 wait() 方法未被 notify() 及时唤醒。
    • Sleeping:线程主动 Thread.sleep() 休眠过长,导致 UI 线程无法及时响应用户操作。
    • DeadLock(死锁) :多个线程互相等待锁释放,形成循环依赖,导致线程无法继续执行。
    • Blocked:线程因锁争用被阻塞,比如多个线程访问同一个资源时,锁未及时释放。
  3. Binder

    • Block(阻塞) :Binder 调用(跨进程通信)如果被卡住,可能是远程进程响应慢或卡死,导致调用方(通常是主线程)被阻塞,进而触发 ANR。
    • 线程池耗尽:Binder 线程池有限,若大量 Binder 请求阻塞,线程池耗尽,导致新请求无法及时处理,引发 ANR。
  4. 内存

    • OOM(内存溢出) :1.由于 OOM 导致应用崩溃前,系统可能会尝试回收内存,这会导致 GC 频繁执行,影响主线程执行。 2.在低内存设备上,系统可能会冻结进程或降低 UI 渲染优先级,导致界面卡死,进而导致 ANR。3.OOM 本身不会直接触发 ANR,但如果 OOM 发生时,主线程正在等待某个资源(例如等待 Bitmap 加载),会导致 ANR。

    • 内存泄漏:对象未被正确释放,导致长期占用大量内存,影响 GC 性能,最终影响 UI 响应速度。

    • GC:大量对象创建与销毁导致频繁 GC,导致主线程等待 GC 结束,从而影响 UI 响应速度。


系统侧

  1. Memory(内存)

    • 内存紧张:系统整体可用内存不足,导致后台进程被杀或 GC 频繁执行,影响前台应用流畅度,引发 ANR。
  2. IO(输入/输出)

    • 过度的磁盘读写(如频繁访问数据库、大文件读写)可能导致 IO 线程阻塞,进而影响 UI 线程的响应速度,引发 ANR。
  3. CPU

    • CPU 负载过高(如后台进程占用大量 CPU 资源),导致主线程的任务无法被及时调度,出现 UI 卡顿甚至 ANR。

总结

  • 主线程耗时 是最常见的 ANR 原因,避免在主线程执行耗时操作。
  • 线程状态问题 需要特别关注死锁、长时间等待等情况。
  • Binder 调用涉及跨进程通信,避免无响应的远程服务影响 UI 线程。
  • 内存管理 方面要避免 OOM 、内存泄露和频繁 GC,减少不必要的对象分配。
  • 系统资源(CPU、IO、Memory) 受限时,会影响应用的运行效率,甚至导致 ANR。