iOS【优化二进制重排】

摘录:ios启动优化:二进制重排

先查看需要优化项目的排列以及大体的Page Fault
1、Xcode:【Build Settings 】-> 【Write Link Map File】 -> YES;
2、然后Clean项目,运行,选择Products 中的项目-> Show in Finder;

3、然后上上层,就是找到【Intermediates.noindex】->【Adorawe.build】->【Release-iphoneos】(选择对应运行模式的)
->【Adorawe.build】->【Adorawe-LinkMap-normal-arm64.txt】

查看一下# Symbols:下排列顺序,以及[AppDelegate application:didFinishLaunchingWithOptions:]大体位置;

符号顺序明显是按照 Compile Sources 的文件顺序来排列的

测试调整:

如一个控制器里创建三个方法,test1,test2,test3;
编译运行,得到到的顺序会是

-[ViewController test1]
-[ViewController test2]
-[ViewController test3]

手动调整顺序:创建一个文件,如testOrder.txt
填写如下内容:

-[ViewController test3]
-[ViewController test2]
-[ViewController test1]

将testOrder.txt文件拖入到项目里,
修改Xcode配置:【Builde Settings】->【Order File】 -【textOrder文件路径(一般(./textOrder.txt);

Clean编译运行,再次按顺序去查看【xxx.txt】文件里顺序是否调整:
结果顺序

-[ViewController test3]
-[ViewController test2]
-[ViewController test1]

使用Clang插桩方式测试

clang 的插桩覆盖的官方文档如下 : clang 自带代码覆盖工具 文档中有详细概述

一般流程:
1、配置Xcode:【Builde Settings】->【Other C Flages】->【-fsanitize-coverage=func,trace-pc-guard】

2、在首页控制器里HomeViewController.m添加方法

头部引入

#import 
#import 
//原子队列  1、先进后出  2、线程安全  3、只能保存结构体
static OSQueueHead symbolList = OS_ATOMIC_QUEUE_INIT;

//定义符号结构体
typedef struct {
    void *pc;
    void *next;//下一个数据的结构体指针地址
}SYNode;

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 < stop; x++)
    *x = ++N;  // Guards should start from 1.
}


void __sanitizer_cov_trace_pc_guard(uint32_t *guard) {
//    if (!*guard) return;  // Duplicate the guard check.

//    汇编一个函数执行完返回会将下一个要执行的函数地址给保存到 x30 寄存器中,将返回值给下一个函数。
//    所以这个函数的命名就是 返回 内存地址。 这里PC 就是拿到的内存地址
    void *PC = __builtin_return_address(0);

    SYNode * node = malloc(sizeof(SYNode));
    *node = (SYNode){PC,NULL};
//    进入 入栈
//    最后一个参数是下一个数据的位置,也就是往上边的*node 的第二位插入
//    offsetof(SYNode, next)  next 成员在 结构体 SYNode 中的偏移值
    OSAtomicEnqueue(&symbolList, node, offsetof(SYNode, next));

}

- (void)timeFilePath {
    
    NSMutableArray * symbolNames = [NSMutableArray array];
        while (YES) {
            SYNode * node = OSAtomicDequeue(&symbolList, offsetof(SYNode, next));
            if (node == NULL) {
                break;
            }
            Dl_info info;
            dladdr(node->pc, &info);

            NSString * name = @(info.dli_sname);
            BOOL isObjc = [name hasPrefix:@"+["] || [name hasPrefix:@"-["];
            NSString * symbolName = isObjc? name : [@"_" stringByAppendingString:name];//c函数前面带下划线
            [symbolNames addObject:symbolName];
            printf("%s \n",info.dli_sname);
        }
    //    symbolNames = [[symbolNames reverseObjectEnumerator] allObjects];//取反
        NSEnumerator * emt = [symbolNames reverseObjectEnumerator];
        NSMutableArray* funcs = [NSMutableArray arrayWithCapacity:symbolNames.count];
        NSString * name;
        while (name = [emt nextObject]) {
            if (![funcs containsObject:name]) {
                [funcs addObject:name];
            }
        }
        //    删掉当前方法(因为这个点击方法不是必须的)
        [funcs removeObject:[NSString stringWithFormat:@"%s",__FUNCTION__]];

        NSString * funcStr = [funcs componentsJoinedByString:@"\n"];

        NSString * filePath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"liujilou.order"];
        NSData * fileContents = [funcStr dataUsingEncoding:NSUTF8StringEncoding];
    //    在路径上创建文件
        [[NSFileManager defaultManager] createFileAtPath:filePath contents:fileContents attributes:nil];


        STLLog(@"=====MMMMMMMM%@",filePath);
}

3、真机运行,当首页显示后,手动点击触发方法【timeFilePath】

4、导出生成的文件
Xcode:【Window】->【Devices and Simulators】->【选择自己手机中INSTALLED APPS列表的对应项目】->[+-符号旁边的设置符号】->【Download ...】下载到桌面;
5、右键显示包内容:【AppData】->【tmp】->【liujilou.order】;
6、可以打开liujilou.order查看一下顺序;
7、liujilou.order拖入到项目里;
8、修改Xcode配置:【Builde Settings】->【Order File】 -【liujilou.order文件路径(一般(./liujilou.order);

查看时间相关
Xcode配置:
DYLD_PRINT_STATISTICS_DETAILS 1,
DYLD_PRINT_STATISTICS 1

或instruments 【App Launch】、【System Trace】

使用Instruments - App Launch查看启动问题
iOS进阶专项分析(八)、深入App启动之dyld、map_images、load_images

你可能感兴趣的:(iOS【优化二进制重排】)