iosapp启动优化(代码片段)

WeaterMr WeaterMr     2022-12-31     410

关键词:

二进制重排数据收集

1.Xcode 可以监测到 main 函数之前耗时时间。
通过添加环境变量可以打印app的启动时间分析(Edit scheme - run- arguments - Environment Variables
main 函数之前的开启时间
DYLD_PRINT_STATISTICS 设置为1
详细的开启时间
DYLD_PRINT_STATISTICS_DETAILS
400毫秒以内属于正常

  • dylib loading time:动态库载入耗时;
  • rebase/binding time:重定位、重绑定;
  • ObjC setup time:OC类注册(OC是一个动态语言,读取二进制的data内容,找到OC的相关的信息,注册OC类;OC的runtime需要维护一张映射表(sel 和 imp 的映射, 类与类名的全局表, 加载mach-O的时候,所有的类都需要加载到全局表中));
  • initializer time:执行load、构造函数耗时;

2.打开instrament 工具 点击System Trace 工具 。点击左上角的红色运行按钮,当应用程序显示第一个页面关闭。并在target栏中搜索Main Thead 找到当前的应用。

3.Build seting -->Linking -->Wright Link Map File 设为yes。
到对应的路径下找到启动时函数调用的一个.text 文档。

二进制原理与分析

虚拟内存的概念:
为了解决内存不足与安全方面的问题,诞生了虚拟内存。每个应用程序都有4G大小的虚拟内存空间,当需要加载应用程序时,操作系统通过每个对应应用的文件偏移量,按需装载到内存中。为了提高效率以分页的形式装载到内存中(在iOS系统中 是 16K , Mac 中是 4K)。这样起到隔离每个应用程序的作用。
由于按需加载,当应用程序使用到某个模块就会加载对应的模块,这个时候系统会抱缺页中断,停止用户操作系统将缺失的叶加载到内存中,并且系统也可以通过计算不活跃的页惊醒覆盖。
当我们启动的时候会有大量的缺页中断,所以虽然一个缺页中短时间很短,用户基本无感知,但是成百上千的缺页中段将有视觉上的观感。二进制重拍的原理是解决不必要的缺页中断,通过进行方法重新排列减少缺页中断的数量。

Clang插桩

添加Clang插桩标记
搜索:Other C Flags
添加编译参数:-fsanitize-coverage=func,trace-pc-guard
运行报错添加对应的两个函数的对应实现,并自定义方法写入文件。

#include <stdint.h>
#include <stdio.h>
#include <sanitizer/coverage_interface.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;
  if (start == stop || *start) return;
//  printf("INIT: %p %p\\n", start, stop);
  for (uint32_t *x = start; x < stop; x++)
    *x = ++N;



//HOOK一切的回调函数!!
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)touchesBegan:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event

    //定义数组
    NSMutableArray<NSString *> * symbleNames = [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];
        [symbleNames addObject:symbolName];
          
    
    //反向遍历数组

    NSEnumerator * em = [symbleNames reverseObjectEnumerator];
    NSMutableArray * funcs = [NSMutableArray arrayWithCapacity:symbleNames.count];
    NSString * name;
    while (name = [em nextObject]) 
        if (![funcs containsObject:name]) //数组没有name
            [funcs addObject:name];
        
    
    //去掉自己!
    [funcs removeObject:[NSString stringWithFormat:@"%s",__func__]];
    
    //写入文件
    //1.编程字符串
    NSString * funcStr = [funcs componentsJoinedByString:@"\\n"];
    NSString * filePath = [NSTemporaryDirectory() stringByAppendingPathComponent:@"hank.order"];
    NSData * file = [funcStr dataUsingEncoding:NSUTF8StringEncoding];
    
    [[NSFileManager defaultManager] createFileAtPath:filePath contents:file attributes:nil];
    
    NSLog(@"%@",funcStr);


配置二进制重排order文件

在对应的路径下找到我们生产的order文件,并且拷贝到工程目录第一层文件夹下,不是引用到工程
在Link 下找到 order file 将路径填写进去。

这时从新启动项目通过上面的第一步方式查看order重拍是否起效。
注意:

  • 1.在拿到order文件后将对应的插桩配置清除。
  • 2.无法监听到framework中的方法。只能监听到自己写的所有方法,函数。
  • 3.注意冷热启动带来的测试影响。

渲染优化

  • 1.cup和GPU
    cpu主要是用来各种计算,解码,GPU主要是通过计算好的数据进行屏幕渲染,也就是屏幕上显示的所用东西,都是通过GPU渲染出来的。
    渲染后,将其放到帧缓存区中,iOS 的帧缓存区是双缓冲机制,有前针缓存,后针缓存。
  • 2.image的处理,对于【uiimage imagewithname:】方法起时有一步隐藏的炒作,就是对image二进制数据进行解码操作,然后在现实到屏幕上
  • 3.离屏渲染
    圆角的设计,可以使用coreGraphics绘制裁剪圆角。

卡顿监控

1.耗电相关的主要来源 cpu,网络,定位,渲染
断点续传
如果仅仅只使用定位可以使用系统的框架,CllocationManager 的快速定位。 requestLocation

启动加载优化

  • 1.减少动态库,合并动态库
  • 2.定期清理不必要的类,分类
  • 3.减少c++虚函数的数量
  • 4.swift尽量使用struct
  • 5.initialize 和 dispatch_once 取代 +load
  • 6.main函数后尽量做一些延时处理。按需加载

安装包瘦身

安装包主要由可执行文件,资源组成
1.资源质量处理
2.去除没有用到的资源:https://github.com/tinymind/LSUnusedResources
可执行文件的瘦身
1.编译器优化,开启strip Linked
2.对一些没有用过的类进行清理,https://www.jetbrains.com/objc/ 检测未使用的代码:菜单栏-code-InspectCode (收费)
推荐:
数据结构与算法: 「严蔚敏」《数据结构》 《大话数据结构与算法》
网络层 《http权威指南》《TCP/IP详解卷1:协议》
架构与设计模式

如何实现iosapp的冷启动优化(代码片段)

...来良好的使用体验。热启动与冷启动当用户按下home键,iOSApp不会立刻被kill,而是存活一段时间,这段时间里用户再打开App,App基本上不需要做什么,就能还原到退到后台前的状态。我们把App进程还在系统中,无需开启新进程的... 查看详情

iosapp启动优化(代码片段)

二进制重排数据收集1.Xcode可以监测到main函数之前耗时时间。通过添加环境变量可以打印app的启动时间分析(Editscheme-run-arguments-EnvironmentVariables)main函数之前的开启时间DYLD_PRINT_STATISTICS设置为1详细的开启时间DYLD_PRINT_STATI... 查看详情

《iosapp性能检测》(代码片段)

...f0c;通过指标值的变化来看优化效果,于是笔者调研了iOSAPP性能检测的一些方法,在此总结一下。首先,要明确性能检测都需要关注哪些指标,笔者列举了以下几个主要的,后 查看详情

iosapp启动优化

...务需求进⾏合理优化。接下来进⼊正题,本⽂将会以iOSApp的启动优化为展开点进⾏探讨。前言作为程序猿来说,“性能优化”是我们都很熟悉的词,也是我们需要不断努⼒以及持续进⾏的事情;其实优化是⼀个很... 查看详情

android性能优化之启动优化(代码片段)

Android性能优化之启动优化1.启动窗口优化Android系统在Activity的窗口尚未启动完成前,会先显示一个启动窗口(StartingWindow),等界面的第一帧渲染完成后再从启动窗口切换到真正的界面显示,启动窗口通常情况... 查看详情

android性能优化之启动优化(代码片段)

Android性能优化之启动优化1.启动窗口优化Android系统在Activity的窗口尚未启动完成前,会先显示一个启动窗口(StartingWindow),等界面的第一帧渲染完成后再从启动窗口切换到真正的界面显示,启动窗口通常情况... 查看详情

全志linux系统启动优化启动优化速度方式优化启动流程优化uboot优化kernel等(代码片段)

文章目录1概述2启动速度优化简介2.1启动流程2.2测量方法2.2.1printktime2.2.2initcall_debug2.2.3bootgraph.2.2.4bootchart2.2.5gpio+示波器.2.2.6grabserial.2.3优化方法2.3.1boot0启动优化2.3.1.1非安全启动.2.3.1.2安全启动2.3.2uboot启动优化2.3.2.1完全去掉ubo 查看详情

android性能优化-启动速度优化(代码片段)

文章目录1.启动的状态2.冷启动耗时2.1系统日志统计2.2adb命令统计3.启动分析3.1CPUProfile工具简单教程3.2启动耗时分析3.3使用DebugApi生成.trace文件4.StrictMode严苛模式5.结尾做开发除了实现功能,还要注重优化,性能优化包括的... 查看详情

app启动优化(代码片段)

APP启动优化我们Android开发永远也摆脱不了性能优化的需求,做的App就是给用户用的,随着功能的增加,App启动功能的丰富。点击启动图标时,我们的App启动会出现一个白屏页面。这个非常影响交互体验。这节我们... 查看详情

android性能优化实践与总结(包含启动,内存优化)(代码片段)

...行检测,以数据说话,优化前和优化后有了怎样的提升[TOC]启动优化检测启动时间检测工具任选其一hugo插件,自己定义时间开始和结束手动计算时间.AOP工具AspectJadb的amstart命令启动Activity测量耗时从点击应用的启动图标開始创建出一... 查看详情

android项目优化:启动页面优化(代码片段)

一、启动页黑屏的问题1.1问题现象描述AndroidApp启动页面黑屏的问题,现象表现为:Android 开发App 启动时若没有做特殊处理的话,会出现一瞬间的白屏现象。即使启动页界面就加载一个布局,不做其他耗时处理,貌似也会... 查看详情

android启动优化说明黑白屏处理(代码片段)

Android启动优化说明、黑白屏处理前言正文一、启动来历二、启动说明1.冷启动2.热启动3.温启动4.冷启动流程5.优化时间6.优化方案三、黑白屏处理1.创建启动页2.样式3.运行效果四、源码五、开心一刻前言  正文  在AndroidApp使... 查看详情

启动速度优化记录(代码片段)

启动速度优化初步测试初步测试各个方法耗时:序号测试结果(ms)Freso45DownloadMannager3okCache80imageLoader17Bugly40LoginFromLocal167InitSobot4InitHpplay57initYouZan220测试依据Trace分析:测试依据:具体可以参考https://zhuanlan.zhi 查看详情

iosapp连续闪退检测及对应处理(代码片段)

线上出了一次事故,在退出登录时,正常的用户在退出登录时会清除成功userDefault中的数据,一般只会crash一次,再次打开就会正常,但是有个用户比较特殊,出现了连续闪退,主要原因就是userDefault中的数据没有清除成功,下次再启动app,从... 查看详情

android启动优化-anchortask开源了(代码片段)

前两篇博客介绍了Android启动优化多线程异步加载依赖问题的解决方案-有向无环图,以及如何实现有它。今天,让我们一起来看一下,在Android实战中,怎么实现。Android启动优化(一)-有向无环图Android启动... 查看详情

抖音android性能优化系列:启动优化实践(代码片段)

组件,其初始化就是借助了一个叫ProcessLifecycleOwnerInitializer的ContentProvider进行初始化的。LifeCycle的初始化只是进行了Activity的LifecycleCallbacks的注册耗时不多,我们在逻辑层面上不需要做太多的优化。值得注意的是,如果这类用于... 查看详情

android性能优化之启动耗时测量(代码片段)

Android启动优化之启动耗时测量本文基于Android11.0源码分析,涉及如下文件frameworks/base/services/core/java/com/android/server/wm/ActivityMetricsLogger.javaframeworks/base/services/core/java/com/android/server/wm/ActivityR 查看详情

android性能优化之启动耗时测量(代码片段)

Android启动优化之启动耗时测量本文基于Android11.0源码分析,涉及如下文件frameworks/base/services/core/java/com/android/server/wm/ActivityMetricsLogger.javaframeworks/base/services/core/java/com/android/server/wm/ActivityR 查看详情