小工具知识网

当前位置: 首页 > 行业知识 > iOS App冷启动优化:二进制重排

行业知识

iOS App冷启动优化:二进制重排

2026-10-20 18:03:26 来源:互联网转载

原理

��        二进制文件中方法的加载顺序, 取决于方法在代码文件中的书写顺序,而不是调用顺序。 应用程序启动时会调用到的方法是有限的,但可能分散在很多个。 由于内存是分页管理的,要加载就要 整页加载。 这就导致很多完全还用不到的方法,会在应用启动时就会被加载到内存,这需要开辟大量内存页,进而增加大量启动耗时。

        如果将BeforeMain阶段用到的方法都找出来出来,让他们在同一或相近的内存页中顺序提前加载,就可以大大减少应用启动时缺页异常出现的概率。

技术要点

     (1)枚举出应用启动时会调用到的方法,将其保存到.order文件中

        可行的方案是Clang插桩:

        

        首先,我们在项目的Build Settings中搜索并设置 Other C Flags/ Other C++ Flags 为 -fsanitize-coverage=func,trace-pc-guard。如果有swift代码,需要设置 Other Swift Flags 设置为 **** -sanitize-coverage=func -sanitize=undefined, 这样应用启动时所有方法都的边缘都被插入了__sanitizer_cov_trace_pc_guard(...)方法的调用。

        然后, 我们只需要实现__sanitizer_cov_trace_pc_guard_init(uint32_t *start, uint32_t *stop)方法, 然后使用dladdr()方法, 就可以将被调用的方法信息枚举出来,然后将其写入.order文件中即可 。                

//原子队列static  OSQueueHead symbolList = OS_ATOMIC_QUEUE_INIT;//定义符号结构体typedef struct {    void *pc;    void *next;}SYNode;- (void)viewDidLoad {    [super viewDidLoad];    [self genrateOrderFile];}void __sanitizer_cov_trace_pc_guard_init(uint32_t *start, uint32_t *stop) {  static uint64_t N;  // Counter for the guards.  if (start == stop || *start) return;  // Initialize only once.  printf("INIT: %p %p\n", start, stop);  for (uint32_t *x = start; x pc, &info);        NSString * name = @(info.dli_sname);        BOOL  isObjc = [name hasPrefix:@"+["] || [name hasPrefix:@"-["];        NSString * symbolName = isObjc ? name: [@"_" stringByAppendingString:name];        [symbolNames addObject:symbolName];    }    //取反    NSEnumerator * enumerator = [symbolNames reverseObjectEnumerator];    //去重    NSMutableArray *funcs = [NSMutableArray arrayWithCapacity:symbolNames.count];    NSString * name;    while (name = [enumerator nextObject]) {        if (![funcs containsObject:name]) {            [funcs addObject:name];        }    }    [funcs removeObject:[NSString stringWithFormat:@"%s",__FUNCTION__]];        //写入.order文件    NSString * funcStr = [funcs  componentsJoinedByString:@"\n"];    NSString * filePath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"demo.order"];    NSData * fileContents = [funcStr dataUsingEncoding:NSUTF8StringEncoding];    [[NSFileManager defaultManager] createFileAtPath:filePath contents:fileContents attributes:nil];    NSLog(@"%@",funcStr);}@end

        (2)设置应用在链接时, 根据.order文件顺序加载其中的符号

          只需在项目的Build Settings中搜索“Order File”,配置.order文件即可   

         

上一篇:服务器如何网销产品?

下一篇:戴尔服务器开关线怎么插?