APM监控系统:启动监控

529 阅读2分钟

本文内容是启动监控而不是启动优化,所以这里,会抛出一些知识点,没有再花时间重述概念及原理。

1. 启动流程

1.1 pre-main阶段

对于pre-main阶段,Apple提供了一种测量方法,在 Xcode 中 Edit scheme -> Run -> Auguments 将环境变量DYLD_PRINT_STATISTICS 设为1

控制台会有如下输出,pre-main阶段各过程的耗时。

Total pre-main time: 579.73 milliseconds (100.0%)
         dylib loading time: 182.01 milliseconds (31.3%)
        rebase/binding time: 177.31 milliseconds (30.5%)
            ObjC setup time:  82.17 milliseconds (14.1%)
           initializer time: 138.07 milliseconds (23.8%)

1.2 main()阶段

  1. dyld调用main()
  2. 调用UIApplicationMain()
  3. 调用applicationWillFinishLaunching
  4. 调用didFinishLaunchingWithOptions

2. 优化

2.1 pre-main阶段的优化

要对pre-main阶段的耗时做优化,必须dyld加载的过程

  • dylib loading
  • rebase/binding
  • ObjC setup
  • initializer

2.2 main()阶段的优化

  1. 梳理业务逻辑,把可以延迟执行的逻辑,做延迟执行处理;
  2. ...

2.3 二进制重排

  1. 了解 Page Fault(页错误);
  2. 了解 Clang 插桩

3. 打点

3.1 pre-main阶段打点

#pragma mark - 获取进程开始时间
+ (BOOL)processInfoForPID:(int)pid procInfo:(struct kinfo_proc*)procInfo
{
    int cmd[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, pid};
    size_t size = sizeof(*procInfo);
    return sysctl(cmd, sizeof(cmd)/sizeof(*cmd), procInfo, &size, NULL, 0) == 0;
}

// 在Xocde下运行上报,影响pre-main的计算
+ (NSTimeInterval)processStartTime
{
    struct kinfo_proc kProcInfo;
    if ([self processInfoForPID:[[NSProcessInfo processInfo] processIdentifier] procInfo:&kProcInfo]) {
        return kProcInfo.kp_proc.p_un.__p_starttime.tv_sec * 1000.0 + kProcInfo.kp_proc.p_un.__p_starttime.tv_usec / 1000.0;
    }
    else {
        NSAssert(NO, @"无法取得进程的信息");
        return 0;
    }
}

//使用
NSTimeInterval exeStartTime = [Class processStartTime] / 1000.0;

3.2 main()阶段打点

3.2.1 main函数

int main(int argc, char * argv[]) {
    @autoreleasepool {
        // main start 打点
        // to do ...
        return UIApplicationMain(argc, argv, nil, NSStringFromClass([AppDelegate class]));
    }
}

3.2.1 didFinishLaunchingWithOptions函数

- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions
{
    // main end 打点
    // to do ...
    return YES;
}

3.2.1 home page

在业务首页首屏渲染完成打点。这里注意的是不能在首页请求网络数据完成后再进行打点,这跟启动不是一回事。

4. 生成报表

4.1 平均耗时

请不要太注意这两张测试环境下的报表。哈哈!其实还有更多的报表的,如每个启动阶段的耗时、启动率等。

截屏2022-01-17 下午4.14.46.png

4.2 耗时分布

截屏2022-01-17 下午4.14.56.png

总结

启动优化,没有数据指标,怎么能体现出启动优化的成果呢。首先把各阶段耗时数据上报,通过报表再针对优化。最后通过优化过与未优化报表进行比较,验证启动优化成效。