iOS重排启动优化

原理:

1.Page Fault

进程直接访问物理内存是不安全的,所以操作系统在物流内存上又建立了一层虚拟内存,虚拟内存进行了分页。

当进程访问一个虚拟内存Page而物流内存不存在,会触发一次缺页中断(Page Fault),分配物理内存,有需要还要从磁盘mmap读入数据

通过App Store渠道分发的App,Page Fault还会进行签名验证,所以一次Page Fault的耗时比想象的要多:

2.重排:

编译器生成二进制代码时,默认按照链接的.o顺序写文件,按照.o内部顺序写函数,如果函数跨页了,就会触发多次Page Fault,所以把函数排到一个Page里,只需要一次Page Fault

重排:

1.build Setting中搜索order file
2.添加自定义的.order地址
3.程序按照order里的内容调用方法

那如何获取程序启动时方法调用顺序

插桩:

1.Build Settings 搜索 other c flags,添加-fsanitize-coverage=trace-pc-guard参数
2.粘贴如下代码到项目
/#import "Hook.h"

/#import <dlfcn.h>

/#import <libkern/OSAtomic.h>

//原子队列

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.

// // 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);

// Dl_info info;

// dladdr(PC, &info);

// printf("fname:%s \nfbase:%p \nsname:%s \nsaddr:%p\n",

// info.dli_fname,

// info.dli_fbase,

// info.dli_sname,

// info.dli_saddr);

//

//

// 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 %s\n", guard, *guard, PcDescr);

// if (!*guard) return; // Duplicate the guard check.

/* 精确定位 哪里开始 到哪里结束! 在这里面做判断写条件!*/

void *PC = __builtin_return_address(0);

Dl_info info;

dladdr(PC, &info);

printf("fname:%s \nfbase:%p \nsname:%s \nsaddr:%p\n",

info.dli_fname,

info.dli_fbase,

info.dli_sname,

info.dli_saddr);

if (![[[NSString alloc] initWithUTF8String:info.dli_sname] containsString:@"createOrderFile"]){

// [ViewController createOrderFile];

SYNode *node = malloc(sizeof(SYNode));

*node = (SYNode){PC,NULL};

//进入,因为该函数可能在子线程中操作,所以用原子性操作,保证线程安全

OSAtomicEnqueue(&symbolList, node, offsetof(SYNode, next));

}

//

}

@implementation Hook

+(void)createOrderFile{

NSMutableArray <NSString *> * 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<NSString *> *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:@"hank.order"];

NSData * fileContents = [funcStr dataUsingEncoding:NSUTF8StringEncoding];

[[NSFileManager defaultManager] createFileAtPath:filePath contents:fileContents attributes:nil];

NSLog(@"##########################################funcStr");

NSLog(@"%@",funcStr);

NSLog(@"%@",filePath);

}

@end
3.- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions

里面调用+(void)createOrderFile

4.把得到的hank.order文件拷贝到项目的根目录下。
5.Build Settings中搜索order file,添加hank.order文件的地址(./hank.order或者${SRCROOT}/hank.order)
6.Build Settings 中搜索 link map,如果是Yes则改回No
7.去掉 Other C Flags的参数 -fsanitize-coverage=func,trace-pc-guard
8.去掉 Other Swift Flags的参数 -sanitize-coverage=func 和 -sanitize=undefined
9.注销__sanitizer_cov_trace_pc_guard_init和__sanitizer_cov_trace_pc_guard方法

参考:https://www.jianshu.com/p/ccfa14d64b0a

https://juejin.im/post/6844904095921209351#heading-4

https://mp.weixin.qq.com/s/Drmmx5JtjG3UtTFksL6Q8Q

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,362评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,330评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,247评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,560评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,580评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,569评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,929评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,587评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,840评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,596评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,678评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,366评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,945评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,929评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,165评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,271评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,403评论 2 342