启动优化 二进制重排

时间:2018-06-02 01:57:36来源:杰瑞文章网点击:作文字数:1500字
一、启动优化 冷启动:第一次启动App 热启动 启动优化一般讲的是冷启动 启动阶段:main函数之前、main函数之后 main 阶段: 1、懒加载 2、发挥CPU的价值(多线程进行初始化) 3、启动时避免使用Xib、stroyboard 阶段一、main函数之前 打印启动时间 添加 DYLD_PRINT_STATISTICS dylib loading time: 加载动态库 (优化:建议不要大于6个) rebase/binding time: 修正内部偏移指针/外部符号绑定 (优化:减少OC类) 优化少 ObjC setup time: OC类的注册 (优化:减少OC类) 优化少 initializer time: 加载load方法 (优化:使用懒加载) 阶段二、main函数之后 main 开始 到 第一个界面。 打点,使用BLStopwatch.h和BLStopwatch.m这个类 - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions { [[BLStopwatch sharedStopwatch] start]; int a = 0; for (int i = 0; i < 10000000; i++) { a++; } [[BLStopwatch sharedStopwatch] splitWithDescription:@"didFinishLaunchingWithOptions"]; return YES; } - (void)viewDidLoad { [super viewDidLoad]; //刷新时间: [[BLStopwatch sharedStopwatch] refreshMedianTime]; int a = 0; for (int i = 0; i < 10000000; i++) { a++; }; [[BLStopwatch sharedStopwatch] splitWithDescription:@"viewDidLoad"]; } -(void)viewDidAppear:(BOOL)animated{ [super viewDidAppear:animated]; //刷新时间: [[BLStopwatch sharedStopwatch] refreshMedianTime]; int a = 0; for (int i = 0; i < 10000000; i++) { a++; }; [[BLStopwatch sharedStopwatch] splitWithDescription:@"viewDidAppear"]; [[BLStopwatch sharedStopwatch] stopAndPresentResultsThenReset]; } 二、二进制重排 二进制重排是在main函数之前 物理内存 虚拟内存 : 解决安全问题、解决内存使用率问题 解决安全问题:映射表(页表)(虚拟页表) 解决内存使用率问题:内存分页管理。缺页中断,然后加载到物理内存,加载之前会签名加载的页;如果启动的时候要加载的代码分别在不同的页,那么缺页中断时间就比较长,这时就出现了二进制重排(把启动要加载的代码放在前面几页)。使用内存分页后,就会导致代码的加载都是从0开始的,为了防止黑客,就出现了ASLR。 内存分页技术 MacOS 、linux (4K为一页) iOS(16K为一页) PageFault(缺页中断) 1、command+I 2、选择System Trace 3、点击一下,第一个页面出现后,再点击一下 4、搜索Main Thread 5、选择Main Thread、选择Virtual Memory。File Backed Page in 就是PageFault 二进制重排优化是在链接阶段对即将生成的可执行文件进行重新排列 order_file 1、打开objc4-750源码 libobjc.order存放的是方法的调用顺序,可以用终端cat打开 2、Build Settings中搜索order file load方法的执行顺序 生成LinkMap文件 Build Settings 中搜索 link map,No改为Yes,然后Command+B,build一下,就会生成LinkMap文件 打开LinkMap文件 Address: 函数真实实现的地址(汇编代码的地址)(代码的地址) Size:函数的大小,写的代码的多与少 File:所在文件 Name: 方法名 0x0000000100d30000(ASLR)+00004848(偏移) = 0x100d34848 在+[ViewController load]方法里面打断点,看到的地址和0x0000000100d30000(ASLR)+00004848(偏移) = 0x100d34848相等,dis -s 0x100d34848查看汇编代码 0x100d34848、0x100d3484c、0x100d34850,这些是代码的地址 添加dyz.order文件 在项目的根目录创建一个.order文件,写入如下代码 Build Settings中搜索order file,添加dyz.order文件的地址(./dyz.order或者${SRCROOT}/dyz.order) command + shift + k清空一下缓存,command+B编译一下 再次查看LinkMap文件 Clang插庄 Build Settings 搜索 other c flags,添加-fsanitize-coverage=trace-pc-guard参数 粘贴如下代码到项目 extern "C" 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 %pn", start, stop); [图片上传中...(Snip20200420_13.png-54b663-1587378588681-0)] for (uint32_t *x = start; x < stop; x++) *x = ++N; // Guards should start from 1. } extern "C" void __sanitizer_cov_trace_pc_guard(uint32_t *guard) { if (!*guard) return; // Duplicate the guard check. // If you set *guard to 0 this code will not be called again for this edge. // Now you can get the PC and do whatever you want: // store it somewhere or symbolize it and print right away. // The values of `*guard` are as you set them in // __sanitizer_cov_trace_pc_guard_init and so you can make them consecutive // and use them to dereference an array or a bit vector. void *PC = __builtin_return_address(0); char PcDescr[1024]; // This function is a part of the sanitizer run-time. // To use it, link with AddressSanitizer or other sanitizer. __sanitizer_symbolize_pc(PC, "%p %F %L", PcDescr, sizeof(PcDescr)); printf("guard: %p %x PC %sn", guard, *guard, PcDescr); } 调试 暂停,然后附加,然后x读start内存 读头 x 0x10d4d7490 读尾 x 0x10d4d74c8-0x4,读尾需要减四个字节,因为一个方法占四个字节,而这个0x10d4d74c8地址是尾方法结束的地址,所以如果需要读尾方法的地址,就需要减掉四个字节 静态插庄! 所有方法、函数、block 内部都加入一行代码!调用 __sanitizer_cov_trace_pc_guard dis -s 0x00000001043e9a54 dis -s 0x00000001043e9a54-116 减去偏移值 拿到所有符号。导入dlfcn.h头文件 #import "ViewController.h" #import @interface ViewController () @end @implementation ViewController +(void)initialize { } void(^block1)(void) = ^(void) { }; void test(){ block1(); } +(void)load { } - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. } -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { } 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 %pn", 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. void *PC = __builtin_return_address(0); Dl_info info; dladdr(PC, &info); printf("dli_fname:%s n dli_fbase:%p n dli_sname:%s n dli_saddr:%p n",info.dli_fname,info.dli_fbase,info.dli_sname,info.dli_saddr); // char PcDescr[1024]; // __sanitizer_symbolize_pc(PC, "%p %F %L", PcDescr, sizeof(PcDescr)); // printf("guard: %p %x PC %sn", guard, *guard, PcDescr); } @end while循环,中会调用__sanitizer_cov_trace_pc_guard,会导致一直打印-[ViewController touchesBegan:withEvent:] #import "ViewController.h" #import #import @interface ViewController () @end @implementation ViewController +(void)initialize { } void(^block1)(void) = ^(void) { }; void test(){ block1(); } +(void)load { } - (void)viewDidLoad { [super viewDidLoad]; // Do any additional setup after loading the view. } -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { while (YES) { SYNode * node = OSAtomicDequeue(&symbolList, offsetof(SYNode, next)); if (node == NULL) { break; } Dl_info info; dladdr(node->pc, &info); printf("%s n",info.dli_sname); } } 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 %pn", start, stop); for (uint32_t *x = start; x < stop; x++) *x = ++N; // Guards should start from 1. } //原子队列 static OSQueueHead symbolList = OS_ATOMIC_QUEUE_INIT; //定义符号结构体 typedef struct { void *pc; void *next; }SYNode; void __sanitizer_cov_trace_pc_guard(uint32_t *guard) { if (!*guard) return; // Duplicate the guard check. void *PC = __builtin_return_address(0); SYNode *node = malloc(sizeof(SYNode)); *node = (SYNode){PC,NULL}; //进入 OSAtomicEnqueue(&symbolList, node, offsetof(SYNode, next)); } @end 解决方法 Other C Flags的参数,等号后面加上func,例如-fsanitize-coverage=func,trace-pc-guard 取反、去重、函数符号前面添加下划线(除了OC方法)、添加load 添加load:注销__sanitizer_cov_trace_pc_guard中的if (!*guard) return;,load的守卫是0 -(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event { 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]; [symbolNames addObject:symbolName]; } //取反 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:@"dyz.order"]; NSData * fileContents = [funcStr dataUsingEncoding:NSUTF8StringEncoding]; [[NSFileManager defaultManager] createFileAtPath:filePath contents:fileContents attributes:nil]; NSLog(@"%@",filePath); } 下载下来,显示包内容 项目中如果是OC和Swift混编 1、在Build Settings搜索other swift flags,如果是OC项目,里面没有Swift文件,那么搜索不到Other Swift Flags,只有项目里面有了Swift文件才会搜索到。 2、添加参数-sanitize-coverage=func 和 -sanitize=undefined 3、导入Swift头文件#import "TraceDemo-Swift.h",调用Swift方法[SwiftTest swiftTestLoad]; 4、Swift方法同样可以hook到 最后 把得到的dyz.order文件拷贝到项目的根目录下。 Build Settings中搜索order file,添加dyz.order文件的地址(./dyz.order或者${SRCROOT}/dyz.order) Build Settings 中搜索 link map,如果是Yes则改回No 去掉 Other C Flags的参数 -fsanitize-coverage=func,trace-pc-guard 去掉 Other Swift Flags的参数 -sanitize-coverage=func 和 -sanitize=undefined 注销__sanitizer_cov_trace_pc_guard_init和__sanitizer_cov_trace_pc_guard方法 结束,打包上线
作文投稿

启动优化 二进制重排一文由杰瑞文章网免费提供,本站为公益性作文网站,此作文为网上收集或网友提供,版权归原作者所有,如果侵犯了您的权益,请及时与我们联系,我们会立即删除!

杰瑞文章网友情提示:请不要直接抄作文用来交作业。你可以学习、借鉴、期待你写出更好的作文。

说说你对这篇作文的看法吧

最新发表的关于快乐的作文

    SQL Error: select id,classid,ttid,onclick,plnum,totaldown,newspath,filename,userid,username,firsttitle,isgood,ispic,istop,isqf,ismember,isurl,truetime,lastdotime,havehtml,groupid,userfen,titlefont,titleurl,stb,fstb,restb,keyboard,eckuid,title,ftitle,newstime,titlepic,smalltext,writer,diggtop from ***_ecms_news where (classid='269') order by newstime desc limit 10

最受欢迎的关于快乐的作文

    SQL Error: select id,classid,ttid,onclick,plnum,totaldown,newspath,filename,userid,username,firsttitle,isgood,ispic,istop,isqf,ismember,isurl,truetime,lastdotime,havehtml,groupid,userfen,titlefont,titleurl,stb,fstb,restb,keyboard,eckuid,title,ftitle,newstime,titlepic,smalltext,writer,diggtop from ***_ecms_news where (classid='269') order by onclick desc limit 10