性能深度分析之SystemTrace

本文通过一个实例分析了在App性能优化过程中,当Time Profiler无法提供足够信息时,如何利用System Trace进行深度分析。System Trace揭示了线程状态、系统负载、内存映射等关键信息,帮助定位主线程被阻塞的原因,如锁的互斥、线程优先级等问题,从而提升App性能。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

前言

App中大多数的性能指标都和时间相关,如启动速度,列表滑动FPS,页面打开耗时等等。为了优化这些指标,我们需要了解时间都消耗在哪里。

通常我们会打开Time Profiler,通过聚合Call Stack来分析和优化代码耗时。偶尔会出现优化后Time Profiler已经没有什么高耗时的Call Stack,但列表滑动仍然掉帧,这时候应该怎么办呢?

不妨试试System Trace~

一个实际例子

用dyld提供的C接口来注册image加载的回调是一种常见做法,第一次注册回调的时候会立刻把当前已经加载的image回调,所以如果回调函数里有耗时操作,我们一般会在子线程注册。

模拟启动的时候注册dyld回调:

在这里插入图片描述

接着在真机上运行这段代码,发现在启动页面会卡很久:

为什么这里会卡很久呢?

试试Time Profiler?

就不具体讲解Time Profiler的用法了,相关资料网上很多,通过分析我们可以拿到如下的调用栈:

在这里插入图片描述
嗯~??不对啊,明明耗时好几秒,怎么统计出来的只有堆栈142ms。可以看到Time Profiler提供的信息有限,以下两条算是比较有用的:

  1. 区间选中有3.17s,但是统计到的调用栈却只有142ms
  2. iPhone 6一共只有两个Core,两个Core在这段时间内,大部分时候都是空闲的。

似乎线程在等待什么?

System Trace

System Trace一个比较大的优势是可以看到线程的状态,分析上面的代码(如下图),发现主线程有一段3s左右的时间被block住了,通过右侧的调用栈能看到主线程在didFinishLaunching中调用了imageNamed后者触发了dlopen,dlopen里在等待一个互斥锁

在这里插入图片描述
切换到Events:Thread State,可以看到线程切换的每一个事件,和状态切换的发生的原因,切换后再选中主线程被block的这段时间,观察这个事件的下一个事件,因为下个事件通常是锁被释放,线程重新进入可执行的状态。

在这里插入图片描述
我们发现,主线程因为线程0x9e1f释放锁才进入了可执行的状态。这时候把线程0x9e1f也pin一下,观察到主线程被block这段时间,这个线程在不停的

评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值