美文网首页
iOS项目二进制重排效果分析

iOS项目二进制重排效果分析

作者: CoderShmily | 来源:发表于2020-05-07 16:28 被阅读0次

分支:zebra_v.2.7.2_xiaopu
测试机信息:8P手机 iOS13.3.1 未越狱(越狱会加载mobilesubrstrate动态库很耗时) 正式环境 无权限认证提示 无首次引导图 wifi
Xcode Version:11.3.1

一、 测试重排前的缺页异常次数和pre-main时间

  • 手机环境准备
    测试过程中发现6s、8P会在重启后偶尔后台还会有之前的进程。为了避免影响,每次测试前,杀掉后台所有进程,再重启手机,确保APP真正处于冷启动。

  • Xcode测试流程
    首先Xcode跑对应项目到手机上,然后每次杀后台,重启,打开Xcode选中 Open Developer Tool 的Instruments面板,选择System Trace,选择真机设备,点击运行按钮,等待首页出现点击⏹停止,等待分析完成。
    删除过滤条件,直接输入main,找到项目的target箭头展开,点击Main thread,
    根据图中选择Virtual Memory 查看 File Backed Page In次数.


    Pasted Graphic 13.png
  • 重排前5次的缺页异常(Page Fault)测试数据如下


    image.png
    image.png
    image.png
    image.png
    image.png
  • 修改配置,在Xcode控制台输出pre-main


    image.png
  • 每次杀进程,重启,Xcode运行,控制台打印结果


    pre-main time 1.2 seconds (100.0;.png
    Total pre-main time 1.1 seconds (100.0).png
    Total pre-main time 1.1 seconds (100.0).png
    pre-main time 1.1 seconds (100.0).png
    Total pre-main time 1.2 seconds (100.0).png

二、输出项目启动的Orderfile,注意代码放置的位置,会影响最后生成的Orderfile大小,也会影响重排后缺页异常的次数。

参考源码如下

#import "ViewController.h"
#import <dlfcn.h>
#import <libkern/OSAtomic.h>
@interface ViewController ()
@end

@implementation ViewController
+ (void)load{
    
}
- (void)viewDidLoad {
    [super viewDidLoad];
    testCFunc();
    [self testOCFunc];
}
- (void)testOCFunc{
    NSLog(@"oc函数");
}
void testCFunc(){
    LBBlock();
}
void(^LBBlock)(void) = ^(void){
    NSLog(@"block");
};

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)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event{
    NSMutableArray<NSString *> * symbolNames = [NSMutableArray array];
    while (true) {
        //offsetof 就是针对某个结构体找到某个属性相对这个结构体的偏移量
        SymbolNode * node = OSAtomicDequeue(&symboList, offsetof(SymbolNode, 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];
        
        //去重
        if (![symbolNames containsObject:symbolName]) {
            [symbolNames addObject:symbolName];
        }
    }

    //取反
    NSArray * symbolAry = [[symbolNames reverseObjectEnumerator] allObjects];
    NSLog(@"%@",symbolAry);
    
    //将结果写入到文件
    NSString * funcString = [symbolAry componentsJoinedByString:@"\n"];
    NSString * filePath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"lb.order"];
    NSData * fileContents = [funcString dataUsingEncoding:NSUTF8StringEncoding];
    BOOL result = [[NSFileManager defaultManager] createFileAtPath:filePath contents:fileContents attributes:nil];
    if (result) {
        NSLog(@"%@",filePath);
    }else{
        NSLog(@"文件写入出错");
    }
    
}
//原子队列
static OSQueueHead symboList = OS_ATOMIC_QUEUE_INIT;
//定义符号结构体
typedef struct{
    void * pc;
    void * next;
}SymbolNode;

void __sanitizer_cov_trace_pc_guard(uint32_t *guard) {
    //if (!*guard) return;  // Duplicate the guard check.
    
    void *PC = __builtin_return_address(0);
    
    SymbolNode * node = malloc(sizeof(SymbolNode));
    *node = (SymbolNode){PC,NULL};
    
    //入队
    // offsetof 用在这里是为了入队添加下一个节点找到 前一个节点next指针的位置
    OSAtomicEnqueue(&symboList, node, offsetof(SymbolNode, next));
}
@end

相关文章

网友评论

      本文标题:iOS项目二进制重排效果分析

      本文链接:https://www.haomeiwen.com/subject/rxvaghtx.html