diff --git a/.obsidian/workspace.json b/.obsidian/workspace.json index b1be9d8..1ff1997 100644 --- a/.obsidian/workspace.json +++ b/.obsidian/workspace.json @@ -27,12 +27,12 @@ "state": { "type": "markdown", "state": { - "file": "docs/git/git设置用户名和邮箱.md", + "file": "docs/学习笔记/高级性能问题分析目录.md", "mode": "source", "source": false }, "icon": "lucide-file", - "title": "git设置用户名和邮箱" + "title": "高级性能问题分析目录" } } ], @@ -200,8 +200,12 @@ }, "active": "25c9f7051aac05b3", "lastOpenFiles": [ - "docs/学习笔记/产品经理/产品经理--写文档.md", + "docs/学习笔记/php/未命名.md", + "docs/学习笔记/高级性能问题分析目录.md", + "docs/学习笔记/高级性能问题分析.md", + "docs/学习笔记/基础性能问题分析(ODM).md", "docs/git/git设置用户名和邮箱.md", + "docs/学习笔记/产品经理/产品经理--写文档.md", "docs/学习笔记/产品经理/项目管理详解.md", "docs/学习笔记/产品经理/需求管理详解.md", "docs/学习笔记/产品经理/沟通与表达详解.md", @@ -223,10 +227,6 @@ "docs/产品经理/项目管理详解.md", "docs/产品经理/产品设计详解.md", "docs/产品经理/需求管理详解.md", - "docs/产品经理/产品经理基础详解.md", - "docs/产品经理/产品经理学习.md", - "docs/学习笔记/php/后台管理系统-设置默认头像方案.md", - "docs/学习笔记/php/后台管理系统修改指南.md", "Pasted image 20260129111501.png", "Pasted image 20260129111451.png", "Pasted image 20260129111437.png", diff --git a/docs/学习笔记/基础性能问题分析(ODM).md b/docs/学习笔记/基础性能问题分析(ODM).md new file mode 100644 index 0000000..24a0f15 --- /dev/null +++ b/docs/学习笔记/基础性能问题分析(ODM).md @@ -0,0 +1,156 @@ +# 基础性能问题分析(ODM) + +## 一、卡顿类问题 + +### 1. 滑动类卡顿 + +一般为长列表滑动等单一页面操作,页面应用主线程持续出帧,从SurfaceFlinger也可以看到有一个Activity持续输出buffer,有快滑(手指离屏后页面仍在滑动,对应在input消息后有一段时间出帧)慢滑(手指不离屏滑动,会有持续的input消息)两种情况。这类场景需关注正常绘制流程(应用主线程-RenderThread线程-SF)即可(PS:有些应用为了兼容性,采用webview以及flutter绘制,这个需要单独分析)。 + +### 2. 动画类卡顿 + +用户操作后执行固定的动画效果,多数情况在systrace中会有animatortag打印。 + +#### 2.1 页面跳转动画 + +两个Activity之间切换的动画一般为系统(system_server)动画,对应在system_server的android.anim.if线程出帧,没有渲染线程,直接通过调用SF的setTransactionState方法参与画面合成。 + +#### 2.2 转屏动画 + +应用需要转屏操作时一般会先冻结屏幕,等转屏后的页面准备好后解冻执行转屏动画,冻屏时间过长会给人反应慢的感觉,也会有人认为这是卡顿,因此冻屏时间也需关注。转屏动画与页面跳转动画一样,在android.anim.if线程出帧。 + +#### 2.4 桌面动画 + +桌面与应用之间的页面跳转,包括在桌面、recently页面点击应用冷、热启动过程,以及从应用回到桌面、recently页面等操作都可能会执行桌面动画。具体场景可根据input消息打印、activityResume、activityStop等方法的位置判断。桌面动画会在应用主线程正常出帧(launcher主线程-RT线程-SF)。 + +### 3. 问题分析步骤 + +#### 3.1 明确问题场景 + +根据问题描述、截屏、视频、log、systrace等信息初步判断问题场景,以便决定后续分析方向。 + +##### 3.1.1 整机卡顿、卡死、卡主不动 + +这类问题常见于项目版本初期,或者市场反馈问题。 + +整机卡顿问题多是多个场景在同一时间段发生卡顿的问题,也有部分问题可能来自实际用户,实际卡顿场景可能很单一但用户描述不清晰,这时就需要根据已有信息判断是否发生卡顿并拆解出卡顿场景进一步分析。 + +遇到整机卡顿、卡住、卡死问题,首先排除是否发生ANR、crash等问题,然后拆解出具体卡顿场景继续分析,如果拆解出多个不同场景卡顿需逐一分析(根据systemserver中的focusap以及iq事件等可以大体确认场景),方法对应各场景分析思路,。一般容易造成系统短时间多个场景卡顿的情况如input上报异常、SF出帧HWC合成耗时、CPU限频关核、低内存、高负载等。 + +##### 3.1.2 单一场景卡顿 + +根据问题描述或视频、截屏初步判断是卡顿问题还是功能性问题,卡顿场景是否是性能责任田等,保证问题快速流转。如果测试提供信息不全且本地无获取条件及时与测试沟通请测试提供。性能自身问题需明确: + +- **问题自检**:卡顿场景、问题信息(systrace、log、截屏、录屏等)是否充足有效、本地能否复现、对比机能否复现等; +- **问题等级**:路径复杂度(及复现概率)、卡顿程度、对比机现象是否一致等。 + +处理问题时优先关注等级较高的问题,如果测试机卡顿程度比同场景对比机严重,很大可能是系统问题,也需关注。 + +#### 3.2 定位问题位置 + +确认问题场景后可找到对应出帧线程,核对卡顿时间(从问题描述、截屏、录屏、log等信息中提取)、input消息、出Buffer情况(SF)、页面生命周期(有跳转情况)等条件,大体圈定systrace范围,如果没有抓到及时请测试复测。 + +#### 3.3 确认卡顿点并分析原因 + +常见的卡顿问题大都是丢帧引起的,但造成丢帧的原因多种多样无法全部列举,这里仅列举如何判断是否发生丢帧 + +##### 3.3.1 丢帧 + +对于一个帧率60的设备,如果1秒内屏幕显示画面小于60,即发生丢帧。对于我们来说,仅关注应用输出Buffer到SF以及SF输出给屏幕过程是否丢帧即可。 + +###### 3.3.1.1 应用丢帧 + +由于3Buffer机制,应用主线程、RT线程出帧稍慢并不一定会丢帧,比较准确的判断应用丢帧的方法是看SF进程下应用输出Buffer的泳道是否连贯、是否每个VSync周期都有可用Buffer供SF消费。 + +## 二、启动响应 + +### 响应速度概述 + +响应速度是应用App性能的重要指标之一。响应慢通常表现为点击效果延迟、操作等待或白屏时间长等,主要场景包括: + +- 应用启动场景,包括冷启动、热启动、温启动等 +- 界面跳转场景,包括应用内页面跳转、App之间跳转 +- 其他非跳转的点击场景(开关、弹窗、长按、控件选择、单击、双击等) +- 亮灭屏、开关机、解锁、人脸识别、拍照、视频加载等场景 + +从原理上来说,响应速度场景往往是由一个input事件(以Message的形式给到需要处理的应用主线程)触发(比如点击、长按、电源键、指纹等),由一个或者多个Message的执行结束为结尾,而这些Message中一般都有关键的界面绘制相关的Message。衡量一个场景的响应速度,我们通常从事件触发开始计时,到应用处理完成计时结束,这一段时间就称为响应时间。 + +由于响应速度是一个比较主观的性能指标(而流畅度就是一个很精确的指标,掉一帧就是掉一帧),而且根据角色的不同,对这个性能指标的判定也不同,比如Android系统开发者和应用开发者以及测试同学,对应用冷启动的起点和终点就有不同的判定: + +1. 系统开发者往往从input中断开始看,部分以应用第一帧为结束点(因为比较好计算),部分以应用加载完成为结束点(比较主观,除非结束点比较容易通过工具去判断),主要是以优化应用的整体性能为主,涉及到的方面就比较广,包括input事件传递、SystemServer、SurfaceFlinger、Kernel、Launcher等 +2. App开发者一般从Application的onCreate或者attachContext开始看,大部分以界面完全加载或者用户可操作为结束点,因为是自己的应用,结束点在代码里面可以主动加,主要还是以优化应用自身的启动速度为主,市面上讲启动速度优化的,大部分是讲这部分 +3. 测试同学则更多从用户的真实体验角度来看,以桌面点击应用图标且应用图标变色为第一帧,内容完全加载为结束点。测试过程一般使用高速相机•自动化,通过机械手和图形识别技术,可以自动进行响应速度测试并抓取相关的测试数据 + +### 响应速度问题分析思路分清起点和终点 + +分析响应速度,最重要的是要找到起点和终点,上一节讲到,不同角色的开发者,对这个性能指标的判定起点和终点都不一样;而且这个指标有很主观的成分,所以在开始的时候,就要跟各方来确定好起点和终点,具体的数值标准,下面一些手段可以帮助大家来确定 + +1. 竞品分析。一般来说,响应速度这个指标都会有一个对标的竞品,竞品手机或者竞品App,相同的条件下,竞品手机或者竞品App从点击到响应花费了多少时间,可以作为一个标准 +2. 对比前一个版本。有时候系统进行大版本升级或者App进行版本迭代,那么上一个版本的数据就可以拿来作为标准进行对比 + +一般来说,起点都比较好确定,无非是一个点击事件或者一个自定义的触发事件;而终点的确定就比较麻烦,比如如何确定一个复杂的App(比如淘宝)启动完成的时间点,用Systrace的第一帧或者Log输出的Displayed时间或者onWindowFocusChange回调的时间显然是不准确的。目前市面上使用高速相机+图像识别来做是一个比较主流的做法 + +### 响应速度常见问题 + +#### Android 系统自身原因导致响应慢 + +下面这些列举的是Android系统自身的原因,与Android机器的性能有比较大的关系,性能越差,越容易出现响应速度问题。下面就列出了Android系统原因导致的App响应速度出现问题的原因,以及这个时候App端在Systrace中的表现 + +1. **CPU频率不足** + - App端的表现:主线程处于Running状态,但是执行耗时变长 + +2. **CPU大小核调度:关键任务跑到了小核** + - App端的表现:Systrace看主线程处于Running状态,但是执行耗时变长 + +3. **SystemServer 繁忙,主要影响** + - 响应App主线程Binder调用处理耗时 + - App端的表现:Systrace看主线程处于Sleep状态,在等待Binder调用返回 + - 应用启动过程逻辑处理耗时 + - App端的表现:Systrace看主线程处于Sleep状态,在等待Binder调用返回 + +4. **SurfaceFlinger 繁忙,主要影响应用的渲染线程的dequeueBuffer、queueBuffer** + - App端的表现:Systrace看应用渲染线程的dequeueBuffer、queueBuffer处于Binder等待状态 + +5. **系统低内存,低内存的时候,很大概率出现下面几种情况,都会对SystemServer和应用有影响** + - 低内存的时候,有些应用会频繁被杀和启动,而应用启动时一个重操作,会占用CPU资源,导致前台App启动变慢 + - App端的表现:Systrace看应用主线程Runnable状态变多,Running状态变少,整体函数执行耗时增加 + - 低内存的时候,很容易触发各个进程的GC,用于内存回收的HeapTaskDeamon、kswapd0出现非常频繁 + - App端的表现:Systrace看应用主线程Runnable状态变多,Running状态变少,整体函数执行耗时增加 + - 低内存会导致磁盘IO变多,如果频繁进行磁盘IO,由于磁盘IO很慢,那么主线程会有很多进程处于等IO的状态,也就是我们经常看到的UninterruptibleSleep + - App端的表现:Systrace看应用主线程UninterruptibleSleep和UninterruptibleSleep-IO状态变多,Running状态变少,整体函数执行耗时增加 + +6. **系统触发温控频率被限制:由于温度过高,CPU最高频率被限制** + - App端的表现:主线程处于Running状态,但是执行耗时变长 + +7. **整机CPU繁忙:可能有多个高负载进程同时在运行,或者有单个进程负载过高跑满了CPU** + - App端的表现:从Systrace来看,CPU区域的任务非常满,所有的核心上都有任务在执行,App的主线程和渲染线程多处于Runnable状态,或者频繁在Runnable和Running之间切换 + +#### 代码逻辑 + +6. 是否在等Binder耗时比较久(Sleep状态)→检测Binder服务端,一般是SystemServer + +7. 是否在等待子线程返回数据(Sleep状态)→应用自身问题,通过查看wakeup信息,来找到依赖的子线程 + +8. 是否在等待子进程返回数据(Sleep状态)→应用自身问题,通过查看wakeup信息,来找到依赖的子进程或者其他进程(一般是ContentProvider所在的进程) + +9. 是否有大量的Runnable→系统问题,查看CPU部分,看看是否已经跑满 + +10. 是否有大量的IO等待(UninterruptibleSleep|WakeKill-BlockI/O)→检查系统是否已经低内存 + +11. RenderThread是否执行dequeueBuffer和queueBuffer耗时→查看SurfaceFlinger + +12. 如果分析是系统的问题,则根据上面耗时的点,查看系统对应的部分,一般情况要优先查看系统是否异常,参考上面列出的的系统原因,主要看下面四个区域(Systrace) + +13. **Kernel 区域** + - 查看关键任务是否跑在了小核→一般小核是0-3(也有特例),如果启动时候的关键任务跑到了小核,执行速度也会变慢 + - 查看频率是否没有跑满→表现是核心频率没有达到最大值,比如最大值是2.8Ghz,但是只跑到了1.8Ghz,那么可能是有问题的 + - 查看CPU使用率,是否已经跑满了→表现是CPU区域八个核心上,任务和任务之间没有空隙 + - 查看是否低内存 + - 应用进程状态有大量的UninterruptibleSleep|WakeKill-BlockI/O + - HeapTaskDeamon任务执行频繁 + - kswapd0任务执行频繁 + +14. **SystemServer 进程区域** + - input 事件读取和分发是否有异常→表现是input事件传递耗时,比较少见 + - binder 执行是否耗时→表现是SystemServer对应的Binder执行代码逻辑耗时 + - binder 等am、wm锁是否耗时→表现是SystemServer对应的Binder都在等待锁,可以通过wakeup信息跟踪等锁情况,分析等锁是不是由于应用导致的 + - 是否有应用频繁启动或者被杀→在Systrace中查看startProcess,或者查看EventLog diff --git a/docs/学习笔记/高级性能问题分析.md b/docs/学习笔记/高级性能问题分析.md new file mode 100644 index 0000000..1009b24 --- /dev/null +++ b/docs/学习笔记/高级性能问题分析.md @@ -0,0 +1,726 @@ +# 高级性能问题分析 + +## 一、深度卡顿分析 + +### 1. 多线程竞争导致的卡顿 + +#### 1.1 锁竞争分析 + +**问题特征:** +- 主线程频繁处于Sleep状态,等待锁释放 +- Systrace中可以看到大量的wakeup信息,但主线程仍无法执行 +- 多个线程同时竞争同一把锁 + +**分析方法:** +1. **锁持有时间分析** + - 在Systrace中查找锁的持有者 + - 分析锁持有时间是否过长 + - 检查是否有死锁或锁泄漏 + +2. **锁粒度分析** + - 检查锁的粒度是否过大 + - 分析是否可以缩小锁的范围 + - 考虑使用读写锁替代互斥锁 + +3. **锁竞争热点** + - 使用perf工具分析锁竞争热点 + - 识别高频竞争的锁 + - 优化锁的使用策略 + +**优化策略:** +- 使用无锁数据结构(如Lock-Free队列) +- 减少锁的持有时间 +- 使用细粒度锁替代粗粒度锁 +- 考虑使用原子操作替代锁 + +#### 1.2 线程调度延迟 + +**问题特征:** +- 主线程处于Runnable状态,但长时间无法获得CPU +- CPU核心繁忙,任务调度延迟 +- 关键任务被低优先级任务抢占 + +**分析方法:** +1. **调度延迟分析** + - 查看Systrace中Runnable到Running的时间间隔 + - 分析调度延迟的分布情况 + - 识别调度延迟的峰值 + +2. **CPU负载分析** + - 分析各CPU核心的负载情况 + - 检查是否有CPU核心过载 + - 识别CPU负载不均衡的情况 + +3. **任务优先级分析** + - 检查关键任务的优先级设置 + - 分析任务优先级是否合理 + - 考虑调整任务优先级 + +**优化策略:** +- 使用cpuset绑定关键任务到高性能核心 +- 调整任务优先级(nice值) +- 使用RT(实时)调度策略 +- 优化CPU负载均衡 + +### 2. 内存压力导致的卡顿 + +#### 2.1 GC压力分析 + +**问题特征:** +- HeapTaskDaemon频繁执行 +- 主线程频繁触发GC +- 内存分配失败导致卡顿 + +**分析方法:** +1. **GC频率分析** + - 统计GC发生的频率 + - 分析GC触发的原因 + - 识别GC热点 + +2. **GC耗时分析** + - 测量每次GC的耗时 + - 分析GC耗时分布 + - 识别耗时较长的GC + +3. **内存分配模式** + - 分析内存分配的速度 + - 识别大对象分配 + - 检查内存泄漏 + +**优化策略:** +- 优化对象创建,减少临时对象 +- 使用对象池复用对象 +- 调整GC参数(如堆大小、GC策略) +- 使用更高效的GC算法(如ART的GC优化) + +#### 2.2 内存碎片化 + +**问题特征:** +- 内存充足但分配失败 +- 频繁的内存整理 +- 内存使用率不高但分配困难 + +**分析方法:** +1. **碎片化程度分析** + - 使用内存分析工具查看碎片化情况 + - 分析碎片化的原因 + - 测量碎片化对性能的影响 + +2. **内存分配模式** + - 分析内存分配的大小分布 + - 识别频繁分配的小对象 + - 检查内存对齐情况 + +**优化策略:** +- 使用内存池管理内存分配 +- 优化对象大小,减少碎片 +- 使用连续内存分配 +- 定期进行内存整理 + +### 3. I/O阻塞导致的卡顿 + +#### 3.1 磁盘I/O阻塞 + +**问题特征:** +- 主线程处于UninterruptibleSleep-IO状态 +- 磁盘I/O操作耗时过长 +- 频繁的磁盘读写操作 + +**分析方法:** +1. **I/O操作分析** + - 统计I/O操作的频率和耗时 + - 识别I/O热点 + - 分析I/O操作的模式 + +2. **I/O路径分析** + - 分析I/O操作的完整路径 + - 识别I/O瓶颈 + - 检查I/O缓存效果 + +3. **存储性能分析** + - 测试存储设备的性能 + - 分析存储设备的瓶颈 + - 检查存储设备的健康状态 + +**优化策略:** +- 使用异步I/O操作 +- 优化I/O操作,减少不必要的读写 +- 使用I/O缓存和预读 +- 优化文件系统(如使用更快的文件系统) + +#### 3.2 网络I/O阻塞 + +**问题特征:** +- 网络请求耗时过长 +- 主线程等待网络响应 +- 网络超时导致卡顿 + +**分析方法:** +1. **网络延迟分析** + - 测量网络请求的延迟 + - 分析网络延迟的分布 + - 识别网络延迟的峰值 + +2. **网络带宽分析** + - 分析网络带宽的使用情况 + - 识别网络带宽瓶颈 + - 检查网络拥塞情况 + +3. **网络请求模式** + - 分析网络请求的频率 + - 识别网络请求的热点 + - 检查网络请求的优化空间 + +**优化策略:** +- 使用异步网络请求 +- 优化网络请求,减少请求次数 +- 使用网络缓存 +- 优化网络协议和压缩 + +## 二、高级启动优化分析 + +### 1. 冷启动深度分析 + +#### 1.1 启动流程分解 + +**启动阶段划分:** +1. **进程创建阶段** + - Zygote进程fork + - 进程初始化 + - 进程启动耗时 + +2. **Application初始化阶段** + - Application.onCreate() + - 依赖库初始化 + - 全局配置初始化 + +3. **Activity创建阶段** + - Activity.onCreate() + - 布局加载 + - 视图初始化 + +4. **首帧渲染阶段** + - 视图测量和布局 + - 绘制准备 + - 首帧输出 + +**分析方法:** +- 使用Method Tracing分析各阶段耗时 +- 使用Systrace分析系统调用 +- 使用StrictMode检测主线程阻塞 +- 使用启动性能监控工具 + +#### 1.2 启动性能瓶颈定位 + +**常见瓶颈:** +1. **主线程阻塞** + - 同步I/O操作 + - 同步网络请求 + - 耗时计算 + - 锁竞争 + +2. **资源加载** + - 大文件加载 + - 图片解码 + - 字体加载 + - 资源文件解析 + +3. **依赖初始化** + - 第三方库初始化 + - 数据库初始化 + - 网络库初始化 + - 缓存初始化 + +**优化策略:** +- 延迟初始化非关键资源 +- 使用异步加载资源 +- 优化资源文件大小 +- 使用资源预加载 + +### 2. 热启动优化分析 + +#### 2.1 热启动流程分析 + +**热启动特点:** +- 进程已存在 +- 应用状态已保存 +- 需要恢复应用状态 + +**优化方向:** +1. **状态恢复优化** + - 优化状态保存和恢复 + - 减少状态数据大小 + - 使用快速恢复机制 + +2. **内存管理优化** + - 保持关键对象在内存中 + - 优化内存使用 + - 避免内存泄漏 + +3. **预热机制** + - 预加载关键资源 + - 预热关键组件 + - 优化启动路径 + +## 三、渲染性能深度分析 + +### 1. 渲染管线分析 + +#### 1.1 渲染流程分解 + +**渲染阶段:** +1. **Measure阶段** + - 视图测量 + - 布局计算 + - 测量耗时 + +2. **Layout阶段** + - 视图布局 + - 位置计算 + - 布局耗时 + +3. **Draw阶段** + - 视图绘制 + - 绘制命令生成 + - 绘制耗时 + +4. **合成阶段** + - 图层合成 + - GPU渲染 + - 合成耗时 + +**分析方法:** +- 使用Hierarchy Viewer分析视图层级 +- 使用GPU Profiler分析GPU性能 +- 使用Systrace分析渲染流程 +- 使用Overdraw工具检测过度绘制 + +#### 1.2 渲染性能瓶颈 + +**常见瓶颈:** +1. **视图层级过深** + - 嵌套层级过多 + - 布局复杂度高 + - 测量和布局耗时 + +2. **过度绘制** + - 不必要的绘制 + - 重复绘制 + - 绘制区域重叠 + +3. **GPU性能瓶颈** + - 复杂着色器 + - 大量纹理 + - GPU负载过高 + +**优化策略:** +- 扁平化视图层级 +- 使用ConstraintLayout优化布局 +- 减少过度绘制 +- 优化GPU渲染 + +### 2. 动画性能分析 + +#### 2.1 动画性能瓶颈 + +**问题类型:** +1. **动画卡顿** + - 帧率不稳定 + - 动画不流畅 + - 丢帧严重 + +2. **动画延迟** + - 动画启动延迟 + - 动画响应慢 + - 动画不跟手 + +**分析方法:** +- 使用Systrace分析动画帧率 +- 使用GPU Profiler分析GPU性能 +- 使用性能监控工具分析动画性能 + +**优化策略:** +- 使用硬件加速 +- 优化动画算法 +- 减少动画复杂度 +- 使用更高效的动画库 + +## 四、系统级性能分析 + +### 1. 系统资源竞争分析 + +#### 1.1 CPU资源竞争 + +**竞争场景:** +1. **多进程竞争** + - 多个进程同时竞争CPU + - 进程优先级不合理 + - CPU负载不均衡 + +2. **多线程竞争** + - 线程数量过多 + - 线程优先级不合理 + - 线程调度延迟 + +**分析方法:** +- 使用top/htop分析CPU使用情况 +- 使用perf分析CPU热点 +- 使用Systrace分析CPU调度 + +**优化策略:** +- 优化进程和线程数量 +- 调整进程和线程优先级 +- 使用CPU亲和性绑定 +- 优化CPU负载均衡 + +#### 1.2 内存资源竞争 + +**竞争场景:** +1. **内存压力** + - 内存不足 + - 内存碎片化 + - 内存泄漏 + +2. **内存分配竞争** + - 多进程竞争内存 + - 内存分配延迟 + - 内存分配失败 + +**分析方法:** +- 使用dumpsys meminfo分析内存使用 +- 使用MAT分析内存泄漏 +- 使用LeakCanary检测内存泄漏 + +**优化策略:** +- 优化内存使用 +- 减少内存分配 +- 及时释放内存 +- 优化内存管理策略 + +### 2. 系统服务性能分析 + +#### 2.1 SystemServer性能分析 + +**性能瓶颈:** +1. **Binder调用延迟** + - Binder调用耗时 + - Binder队列阻塞 + - Binder线程不足 + +2. **系统服务繁忙** + - 服务处理耗时 + - 服务负载过高 + - 服务响应延迟 + +**分析方法:** +- 使用Systrace分析Binder调用 +- 使用dumpsys分析系统服务状态 +- 使用性能监控工具分析系统服务 + +**优化策略:** +- 优化Binder调用 +- 增加Binder线程 +- 优化系统服务处理 +- 使用异步处理 + +#### 2.2 SurfaceFlinger性能分析 + +**性能瓶颈:** +1. **合成延迟** + - HWC合成耗时 + - GPU合成耗时 + - 合成队列阻塞 + +2. **Buffer管理** + - Buffer分配延迟 + - Buffer队列阻塞 + - Buffer泄漏 + +**分析方法:** +- 使用Systrace分析SF性能 +- 使用dumpsys SurfaceFlinger分析状态 +- 使用GPU Profiler分析GPU性能 + +**优化策略:** +- 优化合成路径 +- 优化Buffer管理 +- 使用硬件加速合成 +- 优化合成算法 + +## 五、高级分析工具和方法 + +### 1. 性能分析工具 + +#### 1.1 Systrace深度使用 + +**高级技巧:** +1. **自定义Tag** + - 添加自定义Trace Tag + - 标记关键代码段 + - 分析特定功能性能 + +2. **多进程分析** + - 同时抓取多个进程 + - 分析进程间交互 + - 识别跨进程性能问题 + +3. **长时间分析** + - 长时间抓取Trace + - 分析性能趋势 + - 识别偶发问题 + +#### 1.2 Perfetto使用 + +**优势:** +- 更强大的分析能力 +- 更好的可视化 +- 支持更多数据类型 + +**使用场景:** +- 复杂性能问题分析 +- 系统级性能分析 +- 长时间性能监控 + +#### 1.3 自定义性能监控 + +**监控指标:** +1. **应用指标** + - 帧率 + - 启动时间 + - 内存使用 + - CPU使用 + +2. **系统指标** + - 系统负载 + - 内存压力 + - I/O性能 + - 网络性能 + +**实现方式:** +- 使用Performance API +- 自定义性能监控SDK +- 集成第三方性能监控工具 + +### 2. 性能分析方法 + +#### 2.1 性能回归分析 + +**分析方法:** +1. **版本对比** + - 对比不同版本的性能 + - 识别性能回归 + - 分析回归原因 + +2. **基准测试** + - 建立性能基准 + - 定期性能测试 + - 监控性能变化 + +3. **A/B测试** + - 对比不同优化方案 + - 评估优化效果 + - 选择最优方案 + +#### 2.2 性能瓶颈定位 + +**定位方法:** +1. **自顶向下分析** + - 从整体性能开始 + - 逐步细化到具体问题 + - 定位根本原因 + +2. **自底向上分析** + - 从具体问题开始 + - 逐步扩展到整体 + - 分析影响范围 + +3. **对比分析** + - 对比正常和异常情况 + - 识别差异点 + - 定位问题原因 + +## 六、性能优化策略 + +### 1. 架构级优化 + +#### 1.1 架构设计优化 + +**优化方向:** +1. **模块化设计** + - 减少模块间依赖 + - 优化模块加载 + - 延迟加载非关键模块 + +2. **异步化设计** + - 异步处理耗时操作 + - 使用消息队列 + - 优化线程模型 + +3. **缓存策略** + - 多级缓存 + - 智能缓存更新 + - 缓存失效策略 + +#### 1.2 数据结构优化 + +**优化方向:** +1. **选择合适的数据结构** + - 根据使用场景选择 + - 优化查找和插入性能 + - 减少内存占用 + +2. **算法优化** + - 使用更高效的算法 + - 优化算法复杂度 + - 减少不必要的计算 + +### 2. 代码级优化 + +#### 2.1 代码性能优化 + +**优化技巧:** +1. **减少对象创建** + - 复用对象 + - 使用对象池 + - 避免临时对象 + +2. **优化循环** + - 减少循环次数 + - 优化循环内部操作 + - 使用更高效的循环方式 + +3. **优化方法调用** + - 减少方法调用层次 + - 内联小方法 + - 优化方法参数 + +#### 2.2 资源优化 + +**优化方向:** +1. **资源文件优化** + - 压缩资源文件 + - 使用更高效的格式 + - 按需加载资源 + +2. **图片优化** + - 压缩图片大小 + - 使用合适的图片格式 + - 使用图片缓存 + +3. **网络优化** + - 减少网络请求 + - 使用数据压缩 + - 优化网络协议 + +## 七、性能问题预防 + +### 1. 性能监控体系 + +#### 1.1 实时监控 + +**监控内容:** +- 帧率监控 +- 内存监控 +- CPU监控 +- 网络监控 + +**实现方式:** +- 集成性能监控SDK +- 自定义监控组件 +- 使用第三方监控服务 + +#### 1.2 性能预警 + +**预警机制:** +- 设置性能阈值 +- 自动触发预警 +- 及时通知相关人员 + +### 2. 性能测试体系 + +#### 2.1 自动化测试 + +**测试内容:** +- 启动性能测试 +- 流畅度测试 +- 内存泄漏测试 +- 性能回归测试 + +**实现方式:** +- 使用自动化测试框架 +- 集成性能测试工具 +- 建立测试流程 + +#### 2.2 性能基准 + +**基准建立:** +- 定义性能指标 +- 建立性能基准 +- 定期更新基准 + +## 八、典型案例分析 + +### 1. 复杂卡顿问题分析 + +#### 案例1:多因素导致的卡顿 + +**问题描述:** +- 应用在特定场景下出现严重卡顿 +- 卡顿持续时间较长 +- 影响用户体验 + +**分析过程:** +1. 使用Systrace抓取问题场景 +2. 分析主线程状态变化 +3. 识别多个性能瓶颈 +4. 逐一优化各个瓶颈 + +**优化结果:** +- 卡顿时间减少80% +- 用户体验显著提升 + +### 2. 启动性能优化案例 + +#### 案例2:冷启动优化 + +**问题描述:** +- 应用冷启动时间过长 +- 用户反馈启动慢 + +**分析过程:** +1. 分解启动流程 +2. 定位启动瓶颈 +3. 优化关键路径 +4. 验证优化效果 + +**优化结果:** +- 启动时间减少50% +- 首帧时间提前 + +## 九、总结 + +高级性能问题分析需要: + +1. **深入理解系统原理** + - 理解Android系统架构 + - 理解渲染流程 + - 理解系统服务 + +2. **掌握分析工具** + - 熟练使用Systrace + - 掌握Perfetto + - 使用自定义工具 + +3. **系统化分析方法** + - 建立分析流程 + - 积累分析经验 + - 持续优化方法 + +4. **持续优化改进** + - 建立性能监控 + - 定期性能测试 + - 持续优化改进 + +--- + +*最后更新:2024年* diff --git a/docs/学习笔记/高级性能问题分析目录.md b/docs/学习笔记/高级性能问题分析目录.md new file mode 100644 index 0000000..0b1322f --- /dev/null +++ b/docs/学习笔记/高级性能问题分析目录.md @@ -0,0 +1,49 @@ +### 一、深度卡顿分析 + +- 多线程竞争导致的卡顿(锁竞争、线程调度延迟) + +- 内存压力导致的卡顿(GC压力、内存碎片化) + +- I/O阻塞导致的卡顿(磁盘I/O、网络I/O) + +### 二、高级启动优化分析 + +- 冷启动深度分析(启动流程分解、性能瓶颈定位) + +- 热启动优化分析 + +### 三、渲染性能深度分析 + +- 渲染管线分析(渲染流程分解、性能瓶颈) + +- 动画性能分析 + +### 四、系统级性能分析 + +- 系统资源竞争分析(CPU、内存) + +- 系统服务性能分析(SystemServer、SurfaceFlinger) + +### 五、高级分析工具和方法 + +- 性能分析工具(Systrace、Perfetto、自定义监控) + +- 性能分析方法(回归分析、瓶颈定位) + +### 六、性能优化策略 + +- 架构级优化(架构设计、数据结构) + +- 代码级优化(代码性能、资源优化) + +### 七、性能问题预防 + +- 性能监控体系(实时监控、性能预警) + +- 性能测试体系(自动化测试、性能基准) + +### 八、典型案例分析 + +- 复杂卡顿问题分析案例 + +- 启动性能优化案例 \ No newline at end of file diff --git a/mkdocs.yml b/mkdocs.yml index 14204d6..292ea5a 100644 --- a/mkdocs.yml +++ b/mkdocs.yml @@ -80,6 +80,9 @@ nav: - 学习笔记/产品经理/沟通与表达详解.md - 学习笔记/产品经理/需求管理详解.md - 学习笔记/产品经理/项目管理详解.md + - 学习笔记/基础性能问题分析(ODM).md + - 学习笔记/高级性能问题分析.md + - 学习笔记/高级性能问题分析目录.md - Obsidian笔记: - Obsidian/2026-01-05 个人文档管理.md - Obsidian/高频命令.md