1. 内存信息
1.1 分析应用进程的内存占用情况:
1.1.1 分析应用进程详细内存占用分布情况:
adb shell dumpsys meminfo pid or pkgName
1.1.2 分析应用进程虚拟内存占用情况:
对于32位的应用,虚拟内存占用超过4G时会出现Crash或白屏等稳定性问题。
adb shell showmap pid
adb shell pmap -x pid
adb shell "cat proc/pid/smaps" //记录着应用进程的全部虚拟内存占用详情
adb shell "cat proc/pid/status" VmSize // 表示应用进程占用的虚拟内存总大小
Android系统中32位应用进程的虚拟内存地址空间分布如下图所示
1.1.3 分析进程的kgsl显示内存占用情况:
adb shell cat d/kgsl/proc/4131/mem >launcher_kgsl_mem.txt (其中:gl metrack GPU显示内存,egl metrack Surface显存)
1.1.4 dump应用进程的内存快照(分析Java Heap内存泄漏问题):
adb shell am dumpheap pkgName
然后使用Android SDK提供的相关脚本进行格式转换后,用MAT工具分析抓取到的hprof内存快照文件。
1.1.5 dump应用进程的内存快照(分析Native Heap内存泄漏问题):
1. adb shell setenforce 0
2. adb shell chmod 0777 /data/local/tmp
3. adb shell setprop libc.debug.malloc.program XXX
4. adb shell setprop libc.debug.malloc.options "backtrace_enable_on_signal leak_track"
5. adb shell kill -9 pid
6. adb shell kill -45 pid //enable backtrace
7. adb shell kill-47 pid //在/data/locat/tmp/目录下会生成名为 backtrace_heap.<pid>.txt
8. python development/scripts/native_heapdump_viewer.py --verbose --html backtrace_heap.1585.txt --symbols /out/target/product/qssi/symbols >backtrace _heap.html
1.2 分析系统总体内存占用情况:
分析系统总体内存占用情况:
adb shell "cat proc/meminfo"
分析所有进程内存占用分布情况:
adb shell procrank(结果排行是以PSS的大小而排序)
分析所有进程内存占用分布情况且包括进程优先级信息:
adb shell dumpsys meminfo
2. CPU和GPU信息
2.1 查看运行主频信息:
2.1.1 查看CPU主频信息:
查看CPU当前运行主频:
adb shell "cat /sys/devices/system/cpu/cpu7/cpufreq/scaling_cur_freq"
查看CPU可用主频信息:
adb shell "cat /sys/devices/system/cpu/cpu7/cpufreq/scaling_available_frequencies"
查看CPU最高主频:
adb shell "cat /sys/devices/system/cpu/cpu7/cpufreq/scaling_max_freq"
查看CPU可用的governor管理策略:
adb shell "cat /sys/devices/system/cpu/cpu7/cpufreq/scaling_available_governors"
查看CPU硬件真实主频:
adb shell "cat /sys/kernel/debug/clk/measure_only_apcs_goldplus_post_acd_clk/clk_measure"
开启CPU perf性能模式:
adb shell "echo performance >/sys/devices/system/cpu/cpufreq/policy0/scaling_governor"
adb shell "echo performance >/sys/devices/system/cpu/cpufreq/policy4/scaling_governor"
adb shell "echo performance >/sys/devices/system/cpu/cpufreq/policy7/scaling_governor"
查看最近一段时间系统各进程的CPU占用分布情况:
adb shell dumpsys cpuinfo
查看设备壳温传感器数据
adb shell cat /sys/class/thermal/thermal_message/board_sensor_temp
2.1.2 查看GPU主频信息:
查看GPU当前运行主频:
adb shell "cat /sys/class/kgsl/kgsl-3d0/gpuclk"
查看GPU支持的运行主频:
adb shell "cat /sys/class/kgsl/kgsl-3d0/gpu_available_frequencies"
查看GPU支持的最高主频:
adb shell "cat /sys/class/kgsl/kgsl-3d0/max_gpuclk"
查看GPU可用的governor管理策略:
adb shell cat /sys/class/kgsl/kgsl-3d0/devfreq/available_governors
开启GPU perf性能模式(通过修改min_pwrlevel值来控制修改GPU的运行主频):
adb shell "echo 0 > /sys/class/kgsl/kgsl-3d0/min_pwrlevel"
监测GPU的运行负载和主频信息:
adb shell "while true; do sleep 1; cat /sys/class/kgsl/kgsl-3d0/gpu_busy_percentage; cat /sys/class/kgsl/kgsl-3d0/gpuclk; done;"
2.2 查看进程或线程的运行调度状态信息
查看当前system_server进程中所有处于RT调度的线程信息:
adb shell 'ps -eo pid,tid,nice,cmd,rtprio $(pidof system_server)'
3. 显示问题
3.1 界面显示异常问题:
查看window信息:
adb shell dumpsys window -a (mFocusedWindow 为焦点窗口)
查看SurfaceFlinger侧的Layer图层信息:
adb shell dumpsys SurfaceFlinger
查看activity堆栈信息:
adb shell dumpsys activity activities (结果中mResumedActivity为栈顶前台Activity)
查看display信息:
adb shell dumpsys display
3.2 显示性能掉帧卡顿问题:
查看应用绘制相关信息:
adb shell dumpsys gfxinfo pkgName
应用界面流畅度评估:
1. 首先确定要测试的包名,到 App 界面准备好操作;
2. 执行2-3次 adb shell dumpsys gfxinfo tv.danmaku.bili framestats reset ,这一步的目的是清除历数据;
3. 开始操作(比如使用命令行左右滑动,或者自己用手指滑动);
4. 操作结束后,执行 adb shell dumpsys gfxinfo tv.danmaku.bili framestats 这时候会有一堆数据输出,我们只需要关注其中的一部分数据即可;
5. 重点关注:
Janky frames :超过 Vsync 周期的 Frame,不一定出现卡顿
95th percentile :95% 的值
HISTOGRAM : 原始数值
PROFILEDATA :每一帧的详细原始数据
main日志中搜索如下日志:
adb shell logcat -s OpenGLRenderer (搜索关键字Davey,UI线程卡顿超过700ms,谷歌定位为“冻帧”卡顿,就会打印日志)
3.3 屏幕刷新率问题:
获取屏幕刷新率信息(或者开发者选项开启显示屏幕刷新率):
adb shell dumpsys SurfaceFlinger --dispsync
获取游戏应用上帧帧率:
adb shell dumpsys SurfaceFlinger --latency SurfaceView - com.tencent.tmgp.pubgmhd/com.epicgames.ue4.GameActivity#0
4. 应用启动问题
4.1 通用应用启动命令:
测量应用启动时长:
adb shell am start -W -n com.taobao.taobao/com.taobao.tao.TBMainActivity
观察应用启动总时长日志:
adb shell logcat |grep -i displayed
08-01 10:01:49.360 2322 2365 I ActivityTaskManager: Displayed com.ss.android.ugc.aweme/.splash.SplashActivity for user 0: +681ms
5. 应用稳定性问题
5.1 Crash崩溃问题:
查看Java crash问题原因:
adb shell logcat -s AndroidRuntime
查看native crash问题原因:
addr2line -e xxx.so addr 根据native crash堆栈日志定位crash源代码具体位置(需要对应的符号表信息)
5.2 ANR卡死问题分析:
获取运行时的trace信息:
adb shell kill -3 pid
adb pull data/anr/
查看进程的各个线程的调用堆栈信息 :
adb shell debuggerd -b pid
查看线程的状态的运行状态:
adb shell "ps -A -T pid"
5.3 其它稳定性问题:
一、文件句柄fd泄漏导致的crash:
- 查看进程的打开文件的数量的上限:
adb shell "cat proc/pid/limits"
- 查看当前已经打开的文件句柄信息:
adb shell
cd proc/pid/fd/
二、监控线程开启数量(开启的线程过多会导致进程内存占用过大而出现OOM Crash):
adb shell "cat /proc/pid/status" (其中Threads 字段表示当前开启的线程数量)
6. ART虚拟机调试机制
一、开启profiler或Jit模块的调试日志:
adb root
adb shell stop
adb shell setprop dalvik.vm.extra-opts -verbose:profiler
adb shell start
二、强制进行编译优化,编译应用代码为机器码:
// 主动bg-dexopt编译设备上全部安装的应用
adb shell pm bg-dexopt-job
// 单独编译应用
adb shell cmd package compile -m speed -f com.sina.weibo
adb shell pm compile -r bg-dexopt com.sina.weibo
adb shell cmd package compile -m speed-profile -f com.ss.android.ugc.aweme
// 选择只单独编译应用插件代码
adb shell cmd package compile --secondary-dex -m speed-profile -f com.jingdong.app.mall
三、使用profman工具dump查看应用的profiles热点函数清单文件:
adb shell cmd package dump-profiles com.taobao.taobao
adb pull data/misc/profman/
// 获取应用的ref和cur目录下的所有profile文件Merged后的信息
adb shell pm snapshot-profile com.jingdong.app.mall
四、使用oatdump工具反编译查看oat编译产物机器码文件:
adb shell oatdump --boot-image=/apex/com.android.art/javalib/boot.art:/system/framework/boot-framework.art --image=system/framework/arm64/boot-framework.art
adb shell oatdump --boot-image=/apex/com.android.art/javalib/boot.art:/system/framework/boot-framework.art --image=system/framework/arm64/boot-framework.art --app-image=/data/app/~~gZqoKJnYCwtZyvy_E7y-kw==/com.ss.android.ugc.aweme-acaqZRCDf8RSUjmXx-TuxQ==/oat/arm64/base.art --app-oat=/data/app/~~gZqoKJnYCwtZyvy_E7y-kw==/com.ss.android.ugc.aweme-acaqZRCDf8RSUjmXx-TuxQ==/oat/arm64/base.odex --header-only >output.txt
// 查看应用base.art文件的命令:
adb shell oatdump --app-image=base.art --app-oat=base.odex --instruction-set=arm64 --header-only
// 查看oatdump查看boot image文件
adb shell oatdump --oat-file=/system/framework/arm64/boot-framework.oat
五、使用dexdump命令反编译查看dex文件:
// 反编译查看framework.jar的字节码源文件
adb shell dexdump -d /system/framework/framework.jar
7. 应用包信息
查看应用的package信息:
adb shell dumpsys package pkgName (可以查看应用的permission权限申请信息)
打印系统安装的所有第三方包名:
adb shell pm list packages -3
清理应用缓存数据:
adb shell pm clear pkgName
8. input触控事件调试
dump查看系统input机制信息:
adb shell dumpsys input (可以获取EventHub、InputReader、InputDispacher、Global monitors以及当前触控焦点窗口FocusedWindows的信息)
查看屏幕报点情况是否正常:
adb shell "getevent -ltr"
9. 抓取Trace文件
一、查看Systrace支持的TAG:
adb shell atrace --list_categories
二、查看系统trace机制的各种状态信息:
adb shell
cd /sys/kernel/debug/tracing
四、抓取atrace文件命令:
开始抓:
adb shell atrace -c -b 32768 --async_start gfx input view webview wm am sm audio video binder_lock binder_driver camera hal res dalvik rs bionic power pm ss database network adb vibrator aidl sched freq idle disk sync -a com.android.systemui
停止:
adb shell atrace -c -b 32768 --async_stop -z gfx input view webview wm am sm audio video binder_lock binder_driver camera hal res dalvik rs bionic power pm ss database network adb vibrator aidl sched freq idle disk sync -a com.android.systemui > atracedump.atrace
五、抓取prefetto的shell脚本:
echo -e "\033[32m---------------------------使用说明---------------------------
1.直接执行脚本,例如:“./dump_perfetto_v3.sh test”,15s后脚本自动
终止,会把结果保存在同级目录的result中;
--------------------------------------------------------------\033[0m"
adb shell perfetto \
-c - --txt \
-o /data/misc/perfetto-traces/trace \
<<EOF
buffers: {
size_kb: 522240
fill_policy: RING_BUFFER
}
buffers: {
size_kb: 2048
fill_policy: RING_BUFFER
}
data_sources: {
config {
name: "linux.process_stats"
target_buffer: 1
process_stats_config {
scan_all_processes_on_start: true
}
}
}
data_sources: {
config {
name: "android.surfaceflinger.frametimeline"
}
}
data_sources: {
config {
name: "android.gpu.memory"
}
}
data_sources: {
config {
name: "linux.ftrace"
ftrace_config {
ftrace_events: "power/gpu_frequency"
}
}
}
data_sources: {
config {
name: "linux.sys_stats"
sys_stats_config {
stat_period_ms: 5000
stat_counters: STAT_CPU_TIMES
stat_counters: STAT_FORK_COUNT
}
}
}
data_sources: {
config {
name: "linux.ftrace"
ftrace_config {
ftrace_events: "binder/*"
ftrace_events: "block/*"
ftrace_events: "sched/*"
ftrace_events: "task/*"
ftrace_events: "vmscan/*"
ftrace_events: "mmap_lock/*"
ftrace_events: "gpu_mem/gpu_mem_total"
ftrace_events: "mmap_lock/mmap_lock_start_locking"
ftrace_events: "sched/ww"
ftrace_events: "sched/sched_switch"
ftrace_events: "sched/sched_blocked_reason"
ftrace_events: "power/suspend_resume"
ftrace_events: "sched/sched_wakeup"
ftrace_events: "sched/sched_wakeup_new"
ftrace_events: "sched/sched_waking"
ftrace_events: "power/cpu_frequency"
ftrace_events: "power/cpu_idle"
ftrace_events: "sched/sched_process_exit"
ftrace_events: "sched/sched_process_free"
ftrace_events: "raw_syscalls/sys_enter"
ftrace_events: "raw_syscalls/sys_exit"
ftrace_events: "task/task_newtask"
ftrace_events: "task/task_rename"
ftrace_events: "lowmemorykiller/lowmemory_kill"
ftrace_events: "oom/oom_score_adj_update"
ftrace_events: "ftrace/print"
ftrace_events: "mm_event/mm_event_record"
ftrace_events: "kmem/rss_stat"
ftrace_events: "kmem/ion_heap_grow"
ftrace_events: "kmem/ion_heap_shrink"
symbolize_ksyms: true
atrace_categories: "am"
atrace_categories: "adb"
atrace_categories: "aidl"
atrace_categories: "dalvik"
atrace_categories: "binder_lock"
atrace_categories: "binder_driver"
atrace_categories: "bionic"
atrace_categories: "gfx"
atrace_categories: "input"
atrace_categories: "pm"
atrace_categories: "res"
atrace_categories: "rro"
atrace_categories: "ss"
atrace_categories: "view"
atrace_categories: "wm"
atrace_apps: "*"
}
}
}
duration_ms: 3000
flush_period_ms: 30000
incremental_state_config {
clear_period_ms: 5000
}
EOF
out_dir=~/Android/capture_trace
file_path=${out_dir}/systrace_$(date +%Y%m%d%H%M%S)
if [ -n $1 ]; then
file_path=${file_path}_$1
fi
adb pull /data/misc/perfetto-traces/trace ${file_path}
设备上抓取simpleperf火焰图分析方式:
adb shell simpleperf record --duration 10 -g -o /data/local/traces/perf.data --app com.ss.android.ugc.aweme
adb pull /data/local/traces/perf.data
// 解析生成html可视化网页 (必须Python3.9及以上版本)
python3 report_html.py -i perf.data -o report.html --ndk_path /home/xxx/Android/tool/simpleperf/android-ndk-r27d
// 如果出现report.html在浏览器一直转圈圈打不开的话,把html文件的头可以改成下面,我改成下面很快就打开了
<html><head><link rel="stylesheet" type="text/css" href="<https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.2/css/bootstrap.min.css>"></link> <link rel="stylesheet" type="text/css" href="<https://cdn.datatables.net/1.10.19/css/dataTables.bootstrap4.min.css>"></link> <script src="<https://ajax.googleapis.com/ajax/libs/jquery/3.3.1/jquery.min.js>"></script> <script src="<https://cdnjs.cloudflare.com/ajax/libs/popper.js/1.12.9/umd/popper.min.js>"></script> <script src="<https://cdnjs.cloudflare.com/ajax/libs/twitter-bootstrap/4.1.2/js/bootstrap.min.js>"></script> <script src="<https://cdn.datatables.net/1.10.19/js/jquery.dataTables.min.js>"></script> <script src="<https://cdn.datatables.net/1.10.19/js/dataTables.bootstrap4.min.js>"></script> <script src="<https://www.gstatic.com/charts/loader.js>"></script>
10. selinux机制调试
一、动态开关selinux检查机制:
adb shell setenforce 0 //设置成permissive 模式 adb shell setenforce 1 //设置成enforce 模式
二、查看进程的selinux权限组信息:
adb shell "ps -AZ |grep pid"
三、修改selinux权限后,需要单独编译selinux_policy模块替换验证
11. 屏幕点亮速度分析
adb shell "logcat -s PowerManagerService |grep 'Screen on'"
12. 应用安装速度分析
1. 分析apk文件拷贝的IO性能是否慢?
a.IO拷贝前注意使用如下命令释放磁盘缓存:adb shell "echo 3 > /proc/sys/vm/drop_caches";
b.是否存在fuse的影响?
c.安全检测逻辑的影响?
d.磁盘性能是否存在差异,安兔兔测试跑一下存储?确认是否是三星的存储器和WDC存储器的性能差异(重启手机后,运行命令:adb shell "logcat | grep scsi")?
e.通过adb shell logcat -s InstallStaging // 日志查看安装时的I/O拷贝时长。
2. dex2oat安装的cpuset配置和是否存在限频等:adb shell logcat -s dex2oat64
3. 查看设备UFS型号信息:adb shell "cat sys/devices/platform/soc/1d84000.ufshc/string_descriptors/product_name"
KLUEG8UHDC-B0E1 SUMSUMG 256G
KLUDG4UHDC-B0E1 SUMSUMG 128G
KLUFG8RHDB-B0E1 SUMSUMG 512G
SDINFDK4-256G SANDISK
13. 系统Cgroup进程资源隔离机制调试
13.1 cpuset控制
一、查看设备上的cpuset场景分组信息,限制进程运行在哪个CPU核心:
adb shell
cd dev/cpuset/
二、查看进程的cpuset配置信息:
adb shell "cat proc/pid/status"
14. 打印代码调用堆栈的方法
一、Native的调试调用堆栈打印:
Linux Kernel
dump_stack()
WARN_ON(x)
Native C++
#include "utils/CallStack.h"
android::CallStack cs(“haha”);
Android.bp中加入:
shared_libs [
....
"libutilscallstack",
....
]
Native C
extern "C" void dumping_callstack(void);
void dumping_callstack(void) {
android::CallStack cs("Jamie");
}
ART虚拟机源码中输出调用堆栈方式
#include "runtime_common.h"
Backtrace thread_backtrace(nullptr);
LOG(INFO) << "Backtrace: " << Dumpable<Backtrace>(thread_backtrace) << std::endl;
二、Java调用堆栈打印:
android.os.Debug.getCallers(n)
15. Power电源相关调试
去除电池挂载
adb shell dumpsys battery unplug
查看电源信息以及系统电源锁持锁状况:
adb shell dumpsys power
16.开机速度慢问题分析
一、bootchart的使用
a.生成数据文件和Log
1.adb shell touch /data/bootchart/enabled
2.adb shell "echo 120 > /data/bootchart/start"
3.adb reboot
b.压缩、导出:
1. adb shell
2.cd /data/bootchart/
3.tar -zcf boochart.tgz *
4.adb pull xxx xxx
5.exit
c.生成图表:
java -jar bootchart.jar bootchart.taz
二、日志测量开机速度的方式:
adb shell "logcat -b events |grep -iE 'boot_progress|sf_stop|wm_boot'"
17. 抓取bugreport日志
一、使用如下命令抓取bugreport日志(包含各类dumpsys信息、内存信息、各类日志信息等,还可用于分析功耗问题):
adb shell bugreportz -p
二、使用chkbugreport工具jar包工具将日志转化为可视化网页:
java -jar chkbugreport.jar xxxx.txt
其它
一、使用adb跑整机monkey命令:
adb shell monkey --throttle 500 --ignore-timeouts --ignore-crashes --ignore-native-crashes --ignore-security-exceptions --pct-syskeys 10 --pct-touch 45 --pct-motion 25 --pct-appswitch 20 -c android.intent.category.LAUNCHER -c android.intent.category.MONKEY -c android.intent.category.DEFAULT -v -v 500000
二、设备解锁刷fastboot方法:
1. 开机进入开发者选项,使能OEM锁;
2. adb reboot bootloader ;
3. fastboot flashing unlock 音量下键 选择 UNLOCK选项,机器恢复 ;
4. 解锁成功,然后刷版本就可以了手机正常启动;
5. 进入fastboot模式:adb reboot bootloader ;
6. 查看是否有设备:fastboot devices
7. erase 擦除:fastboot erase dtbo
8. 刷入img:fastboot flash dtbo dtbo.img
9. 重启:fastboot reboot
三、adb查看settings数据库各个字段值的命令:
adb shell settings list global/system
adb shell settings put global/system xxx value
adb shell settings get global/system xxx
四、设备恢复出厂设置:
adb reboot recovery