01 | 崩溃优化(上):关于“崩溃”那些事儿
- anr检测:
- FileObserver 监听 /data/anr/traces.txt 的变化(5.0以后没有权限使用)
- ANR-WatchDog
- SafeLooper
- BlockCanary
- native崩溃日志捕获:Breakpad
03 | 内存优化(上)
VSS - Virtual Set Size 虚拟耗用内存(包含共享库占用的内存)
RSS - Resident Set Size 实际使用物理内存(包含共享库占用的内存)
PSS - Proportional Set Size 实际使用的物理内存(比例分配共享库占用的内存)
USS - Unique Set Size 进程独自占用的物理内存(不包含共享库占用的内存)
获取系统配置:/system/build.prop,如:
dalvik.vm.heapgrowthlimit=256m
dalvik.vm.heapsize=512m
dalvik.vm.stack-trace-file=/data/anr/traces.txt
自身内存占用监控:
Runtime.getRuntime().totalMemory() - Runtime.getRuntime().freeMemory();
查看整体内存分配:
adb shell dumpsys meminfo <package_name|pid> [-d]
adb shell dumpsys activity <package_name|pid> [-d]
04 | 内存优化(下)
GC 监控
long allocCount = Debug.getGlobalAllocCount();
long allocSize = Debug.getGlobalAllocSize();
long gcCount = Debug.getGlobalGcInvocationCount();
05 | 卡顿优化(上):你要掌握的卡顿分析方法:
获取 CPU 核心数
cat /sys/devices/system/cpu/possible
cat proc/cpuinfo:
cat /sys/devices/system/cpu/cpu0/cpufreq/cpuinfo_max_freq:// 获取某个 CPU 的频率
cat proc/stat:// 获取整个系统cpu使用情况
cat /proc/[pid]/stat:// 获取单个进程cpu使用情况
top:查看所有进程cpu占比
vmstat:查看操作系统的虚拟内存和cpu活动
uptime:检查 CPU 在 1 分钟、5 分钟和 15 分钟内的平均负载
proc/self/stat:
utime: 用户时间,反应用户代码执行的耗时
stime: 系统时间,反应系统调用执行的耗时
majorFaults:需要硬盘拷贝的缺页次数
minorFaults:无需硬盘拷贝的缺页次数
proc/self/sched:
nr_voluntary_switches: 主动上下文切换次数,因为线程无法获取所需资源导致上下文切换,最普遍的是 IO。
nr_involuntary_switches: 被动上下文切换次数,线程被系统强制调度导致上下文切换,例如大量线程在抢占 CPU。
se.statistics.iowait_count:IO 等待的次数
se.statistics.iowait_sum: IO 等待的时间
Android 卡顿排查工具
- Traceview:将函数运行的耗时和调用关系写入 trace 文件中(debug和releaes模式下均可用)
- Nanoscope:
- systrace:systrace 工具只能监控特定系统调用的耗时情况
- Simpleperf
06 | 卡顿优化(下):如何监控应用卡顿?
应用卡顿
- 基于消息队列实现,通过替换 Looper 的 Printer实现
- 插桩(Inline Hook 在方法前后加日志)
- Profilo
其它监控:
- 帧率(使用 Choreographer 来监控应用的帧率)
- 生命周期监控(生命周期的耗时和调用次数)
- 线程监控(线程数量多少)
- Android Vitals(Google Play 官方的性能监控服务)
06 | 补充篇 | 卡顿优化:卡顿现场与卡顿分析
Thread 的 getState 方法获取线程状态
Thread.getAllStackTraces() 获得所有线程堆栈
SIGQUIT 信号实现
07 | 启动优化(上):从启动过程看启动速度优化
启动过程分析:
- T1 预览窗口显示
- T2 闪屏显示
- T3 主页显示
- T4 界面可操作
08 | 启动优化(下):优化启动速度的进阶方法
- I/O 优化
- 数据重排(Dex类重排,Dex资源文件重排)
- 类的加载
- 黑科技(保活,插件化和热修复)
09 | I/O优化(上):开发工程师必备的I/O优化知识
cat /proc/meminfo:查看缓存的内存占用情况
MemTotal: 2866492 kB
MemFree: 72192 kB
Buffers: 62708 kB // Buffer Cache
Cached: 652904 kB // Page Cache
查看对应块设备的队列长度和使用的调度算法。
/sys/block/[disk]/queue/nr_requests // 队列长度,一般是 128。
/sys/block/[disk]/queue/scheduler // 调度算法
proc/self/schedstat:
se.statistics.iowait_count:IO 等待的次数
se.statistics.iowait_sum: IO 等待的时间
将所有 block 读写 dump 到日志文件中,这样可以通过 dmesg 命令来查看
echo 1 > /proc/sys/vm/block_dump
dmesg -c grep pid
.sample.io.test(7540): READ block 29262592 on dm-1 (256 sectors)
.sample.io.test(7540): READ block 29262848 on dm-1 (256 sectors)
通过 strace 来跟踪 I/O 相关的系统调用次数和耗时
strace -ttT -f -p [pid]
read(53, "*****************"\.\.\., 1024) = 1024 <0.000447>
read(53, "*****************"\.\.\., 1024) = 1024 <0.000084>
read(53, "*****************"\.\.\., 1024) = 1024 <0.000059>
strace 统计一段时间内所有系统调用的耗时概况
strace -c -f -p [pid]
% time seconds usecs/call calls errors syscall
------ ----------- ----------- --------- --------- ----------------
97.56 0.041002 21 1987 read
1.44 0.000605 55 11 write
10 | I/O优化(中):不同I/O方式的使用场景是什么?
I/O 的三种方式
Page Cache 中脏页写入磁盘机制:/proc/sys/vm 文件或者 sysctl -a | grep vm
// flush 每隔 5 秒执行一次
vm.dirty_writeback_centisecs = 500
// 内存中驻留 30 秒以上的脏数据将由 flush 在下一次执行时写入磁盘
vm.dirty_expire_centisecs = 3000
// 指示若脏页占总物理内存 10%以上,则触发 flush 把脏数据写回磁盘
vm.dirty_background_ratio = 10
// 系统所能拥有的最大脏页缓存的总大小
vm.dirty_ratio = 20
11 | I/O优化(下):如何监控线上I/O操作?
跟据文件保存所挂载的目录的 block size 来确认 Buffer 大小
查看磁盘预读的大小,一般是 128KB
/sys/block/[disk]/queue/read_ahead_kb
统计真正的磁盘读写次数。
/proc/diskstats
块设备名字|读请求次数|读请求扇区数|读请求耗时总和....
dm-0 23525 0 1901752 45366 0 0 0 0 0 33160 57393
dm-1 212077 0 6618604 430813 1123292 0 55006889 3373820 0 921023 3805823
命令模拟 Page Cache 的释放
echo 3 > /proc/sys/vm/drop_caches
14 | 存储优化(下):数据库SQLite的使用和优化
SQL 语句的查询计划
sqlite> EXPLAIN QUERY PLAN SELECT * FROM t1 WHERE a=1 AND b>2;
QUERY PLAN
|--SEARCH TABLE t1 USING INDEX i2 (a=? AND b>?)
15 | 网络优化(上):移动开发工程师必备的网络优化知识
UNIX 网络 I/O 模型
20 | UI 优化(上):UI 渲染的几个关键概念
22 | 包体积优化(上):如何减少安装包大小?
- ProGuard:去掉 Debug 信息或者去掉行号
- Dex 分包
- Dex 压缩 XZ 压缩算法和 7-Zip
- Library 压缩
- Library 合并与裁剪
- 包体积监控:大小监控、依赖监控、规则监控(Matrix-ApkChecker)
安装包内容
23 | 包体积优化(下):资源优化的进阶实践
AndResGuard :资源混淆、极限压缩
无用资源删除:Lint、shrinkResources、realShrinkResources
27 | 编译插桩的三种方法
- AspectJ
- ASM
- ReDex
35 | Native Hook 技术,天使还是魔鬼?
36 | 跨平台开发的现状与应用
40 | 动态化实践