Android Other

JankMan-极致的卡顿分析系统

2022-08-22  本文已影响0人  _Jun

卡顿分析系统

1.系统介绍

2.思路介绍

2.1方法运行数据采集

2.1.1方法ID映射

2.2.2函数记录能力

  1. 在ASM轮训期间,在方法开始和结束位置各插入对应的指令用于实现标记功能

    override fun onMethodEnter() {
        //方法进入
        methodVisitor?.perfettoVisitMethodDelegate(PerfettoCentre.const.METHOD_ENTER, methodId)
        super.onMethodEnter()
    }
    
    override fun onMethodExit(opcode: Int) {
        //方法退出
        methodVisitor?.perfettoVisitMethodDelegate(PerfettoCentre.const.METHOD_EXIT, methodId)
        super.onMethodExit(opcode)
    }
    

    处理退出指令时,catch和return指令也有对应的记录

  2. 在对应的时机插入对应的代码

    this.let { methodVisitor ->
            methodVisitor.visitFieldInsn(
                GETSTATIC,
                "com/d/hookcore/perfetto/PerfettoCore",
                "Companion",
                "Lcom/d/hookcore/perfetto/PerfettoCore$Companion;"
            )
            methodVisitor.visitIntInsn(BIPUSH, enterOrExit)
            methodVisitor.visitIntInsn(SIPUSH, methodId)
            methodVisitor.visitMethodInsn(
                INVOKEVIRTUAL,
                "com/d/hookcore/perfetto/PerfettoCore$Companion",
                "getTraceLine",
                "(II)V",
                false
            )
        }
    
    • 插入完代码的例子如下:
    例:
    private fun initRecycler() {
        //方法开始,第一个参数用于标记进入或者退出,第二个参数用于标记映射的方法ID
        PerfettoCore.getTraceLine(0,12)
        var recyclerView: RecyclerView = findViewById(R.id.rec)
        recyclerView.adapter = NodeAdapter(messageList)
        PerfettoCore.getTraceLine(1,12)
    }
    

2.2.3.运行方法记录内容

说明
当前线程 Main
当前线程ID 1
当前时间秒值 942155.120954153
当前方法标记(进入或退出) 1
当前方法ID 39
当前帧位下标 1

2.2帧数据采集

2.2.1于传统方式的区别

2.2.2FrameMatrix的能力

类别 参数 说明
获取每帧性能数据 FIRST_DRAW_FRAME 表示当前帧是否是当前 Window 布局中绘制的第一帧
INTENDED_VSYNC_TIMESTAMP 当前帧的预期开始时间, 如果此值与 VSYNC_TIMESTAMP 不同,则表示 UI 线程上发生了阻塞,阻止了 UI 线程及时响应vsync信号
TOTAL_DURATION 表示此帧渲染并发布给显示子系统所花费的总时间, 等于所有其他具有时间价值的指标的值之和
VSYNC_TIMESTAMP 在所有 vsync 监听器和帧绘制中使用的时间值(Choreographer 的帧回调, 动画, View#getDrawingTime等)
cpuDuration COMMAND_ISSUE_DURATION 表示向 GPU 发出绘制命令的耗时
SWAP_BUFFERS_DURATION 表示将此帧的帧缓冲区发送给显示子系统所花的时间
uiDuration UNKNOWN_DELAY_DURATION 表示等待 UI 线程响应并处理帧所经过的时间, 大多数情况下应为0
INPUT_HANDLING_DURATION 表示处理输入事件回调的耗时
ANIMATION_DURATION 表示执行动画回调的耗时
LAYOUT_MEASURE_DURATION 表示对 View 树进行 measure 和 layout 所花的时间
DRAW_DURATION 表示将 View 树转换为 DisplayList 的耗时
SYNC_DURATION 表示将 DisplayList 与渲染线程同步所花的时间

2.3.同步算法

2.3.1.同步算法细节

2.3.2.算法合并过程

  1. 如果卡顿帧连续个数到达了开发者定义的个数,那么开始还原

  2. 将首个卡顿帧的开始时间和连续卡顿帧后的第一个不卡顿帧的开始时间作为时间范围,与函数运行数据的时间点进行校准。匹配到函数运行的范围区域,并通过两个指针进行标记

    1. 具体匹配的过程是通过魔改版的二分查找实现
  3. 将标记出的函数运行范围进行导出

    1. 导出的能力是基于NIO实现的
  4. 导出完毕后将函数指针位移到开始位置,重复利用空间

    上述过程均在子线程进行,对主线程无影响,现阶段损耗为3%左右

2.4.可视化展示

2.4.1.线下还原器

2.4.2.支持多端的线下还原器

2.4.2.1.还原格式细节

2.4.3.可视化展示

作者:Dx
链接:https://juejin.cn/post/7125740435506462734

上一篇 下一篇

猜你喜欢

热点阅读