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

原理

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

        如果将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 < stop; x++)*x = ++N;  // Guards should start from 1.
}
void __sanitizer_cov_trace_pc_guard(uint32_t *guard) {void *PC = __builtin_return_address(0);SYNode *node = malloc(sizeof(SYNode));*node = (SYNode){PC,NULL};//写入队列OSAtomicEnqueue(&symbolList, node, offsetof(SYNode, next));
}
// 解析队列并生成.order文件
- (void) genrateOrderFile{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 * enumerator = [symbolNames reverseObjectEnumerator];//去重NSMutableArray<NSString *> *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文件即可   

         

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/708044.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C#知识点-18(多线程、同步、异步编程)

多线程 进程&#xff1a;一般指程序中运行的程序&#xff0c;实际作用是为程序再执行过程中创建好所需的环境和资源。 线程&#xff1a;是进程的一个实体&#xff0c;是cpu用来调度执行程序的最小单元&#xff0c;一个进程可以拥有多个线程。 单线程&#xff1a;进程中只有一…

mysql根据某字段分组查询,每组取前10个

mysql中有一个表叫policy&#xff0c;表的字段有id&#xff0c;title&#xff0c;time&#xff0c;spider_name等等&#xff0c;spider_name是爬虫名称&#xff0c;每个爬虫采集的数据都会有这个标识。请问如何根据spider_name爬虫名称&#xff0c;每一个种类获取10条数据&…

网站添加pwa操作和配置manifest.json后,没有效果排查问题

pwa技术官网&#xff1a;https://web.dev/learn/pwa 应用清单manifest.json文件字段说明&#xff1a;https://web.dev/articles/add-manifest?hlzh-cn Web App Manifest&#xff1a;Web App Manifest | MDN 当网站添加了manifest.json文件后&#xff0c;也引入到html中了&a…

FPGA-FIF0模型与应用场景(IP核)

什么是FIFO FIFO (First In First Out) ,也就是先进先出。FPGA或者ASIC中使用到的FIFO一般指的是对数据的存储具有先进先出特性的一个缓存器,常被用于数据的缓存或者高速异步数据的交互。它与普通存储器的区别是没有外部读写地址线,这样使用起来相对简单,但缺点就是只能顺序写…

python脚本实现全景站点欧拉角转矩阵

效果 脚本 import numpy as np import math import csv import os from settings import *def euler_to_rotation_matrix(roll, pitch, yaw):# 计算旋转矩阵# Z-Y-X转换顺序Rz

随想录算法训练营第四十五天|322.零钱兑换、279.完全平方数

322.零钱兑换 public class Solution {public int CoinChange(int[] coins, int amount) {int[] dpnew int [amount1];int maxint.MaxValue;for(int i0;i<dp.Length;i){dp[i]max;}dp[0]0;for(int i0;i<coins.Length;i){for(int jcoins[i];j<amount;j){if(dp[j-coins[…

leetcode hot100-2

给你一个字符串数组&#xff0c;请你将 字母异位词 组合在一起。可以按任意顺序返回结果列表。 字母异位词 是由重新排列源单词的所有字母得到的一个新单词。我的解法&#xff0c;是错误解法&#xff0c;只能通过 56 / 126 的测试用例 这个题就是想求&#xff0c;用到的所有字…

java多线程编程(学习笔记)入门

一、多线程创建的三种方式 (1)通过继承Thread本身 (2)通过实现runnable接口 (3)通过 Callable 和 Future 创建线程 其中&#xff0c;前两种不能获取到编程的结果&#xff0c;第三种能获取到结果 二、常见的成员方法 方法名称说明String getName()返回此线程的名称void setNam…

[数据集][目标检测]鸟类检测数据集VOC+YOLO格式11758张200类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;11758 标注数量(xml文件个数)&#xff1a;11758 标注数量(txt文件个数)&#xff1a;11758 标…

Docker之数据卷自定义镜像

文章目录 前言一、数据卷二、自定义镜像 前言 Docker提供了一个持久化存储数据的机制&#xff0c;与容器生命周期分离&#xff0c;从而带来一系列好处&#xff1a; 总的来说Docker 数据卷提供了一种灵活、持久、可共享的存储机制&#xff0c;使得容器化应用在数据管理方面更加…

Git 指令深入浅出【3】—— 远程仓库

Git 指令深入浅出【3】—— 远程仓库 一、远程仓库&#xff08;一&#xff09;基本指令1. 配置 SSH 密钥2. 推送远程仓库其他分支推送远程仓库方法1方法2建立分支链接 方法3 3. 合并分支请求 &#xff08;二&#xff09;.gitignore 忽略文件&#xff08;三&#xff09;标签管理…

MVCC【重点】

参考链接 [1] https://www.bilibili.com/video/BV1YD4y1J7Qq/?spm_id_from333.1007.top_right_bar_window_history.content.click&vd_source0cb0c5881f5c7d76e7580fbd2f551074 [2]https://www.cnblogs.com/jelly12345/p/14889331.html [3]https://xiaolincoding.com/mysql…

基于频率增强的数据增广的视觉语言导航方法(VLN论文阅读)

基于频率增强的数据增广的视觉语言导航方法&#xff08;VLN论文阅读&#xff09; 本文提出的方法很简单&#xff0c;将原始图像增加其他随机图像的高频信息&#xff0c;得到增强的图像作为新的样本&#xff0c;与原始的样本交替训练。背后的动机是&#xff0c;vln模型对高频信息…

TV-SAM 新型零样本医学图像分割算法:GPT-4语言处理 + GLIP视觉理解 + SAM分割技术

TV-SAM 新型零样本医学图像分割算法&#xff1a;GPT-4语言处理 GLIP视觉理解 SAM分割技术 提出背景TV-SAM 方法论 提出背景 论文&#xff1a;https://arxiv.org/ftp/arxiv/papers/2402/2402.15759.pdf 代码&#xff1a;https://github.com/JZK00/TV-SAM 利用了GPT-4的强大语…

TCP/IP-常用网络协议自定义结构体

1、TCP/IP模型&#xff1a; 2、TCP/IP- 各层级网络协议&#xff08;从下往上&#xff09;&#xff1a; 1&#xff09;数据链路层&#xff1a; ARP: 地址解析协议&#xff0c;用IP地址获取MAC地址的协议&#xff0c;通过ip的地址获取mac地 …

SpringBoot使用jsoup爬取HTML

原文网址&#xff1a;SpringBoot使用jsoup爬取HTML_IT利刃出鞘的博客-CSDN博客 简介 本文介绍SpringBoot--使用jsoup(Java爬虫工具)的方法。 jsoup 是一款 Java 的 HTML 解析器&#xff0c;它提供了一套非常便利的 API&#xff0c;可通过 DOM、CSS 通过类似于 JQuery 的操作…

Java的基础数据类型有哪些?String是Java的基础数据类型吗?

目录 Java的基础数据类型有哪些&#xff1f; String是Java的基础数据类型吗&#xff1f; Java的基础数据类型有哪些&#xff1f; Java的基础数据类型是Java语言中预定义的几种基本的数据格式&#xff0c;它们在Java虚拟机&#xff08;JVM&#xff09;中有固定的内存占用和…

分享一个FreeSWITCH通道吊死的帖子

https://forum.signalwire.community/t/session-is-pending-when-shutdown-freeswitch/886/7 之前碰到过类似的情况&#xff0c;就是show channels能看到&#xff0c;但是uuid_kill <uuid>报错&#xff0c;说uuid不存在&#xff0c;或者叫僵尸通道 这人真正的问题是&am…

【最新】如何将idea上的项目推送到gitee

1.打开Gitee&#xff0c;在首页&#xff0c;点击“”&#xff0c;创建一个仓库 2.填写仓库基本信息 3.下拉&#xff0c;点击“创建”&#xff0c;出现下方页面&#xff0c;证明仓库创建成功。 4.打开idea&#xff0c;下载gitee的插件&#xff08;此处默认已经下载git&#xff0…

基于React, Redux实现的俄罗斯方块游戏及源码

分享一个俄罗斯方块游戏游戏框架使用的是 React Redux&#xff0c;其中再加入了 Immutable&#xff0c;用它的实例来做来Redux的state。&#xff08;有关React和Redux的介绍可以看 安装 npm install运行 npm start浏览自动打开 http://127.0.0.1:8080/ 打包编译 npm run …