top: процессы и потоки:
На Android 8 и новее команда top реализована в toybox, флаги отличаются от привычного GNU top, и это первый источник путаницы. Запуск без параметров дает интерактивный режим, выход по q или Ctrl+C:
Код: Выделить всё
adb shell topКод: Выделить всё
Tasks: 689 total, 2 running, 687 sleeping, 0 stopped, 0 zombie
Mem: 7.2G total, 6.9G used, 311M free, 14M buffers
Swap: 4.0G total, 1.1G used, 2.9G free, 2.7G cached
800%cpu 52%user 0%nice 41%sys 692%idle 2%iow 9%irq 4%sirq 0%host
PID USER PR NI VIRT RES SHR S[%CPU] %MEM TIME+ ARGS
2841 u0_a312 10 -10 28G 412M 188M S 64.3 5.5 12:41.30 com.example.game
1287 system 18 -2 32G 680M 290M S 21.0 9.1 188:12.55 system_serverДля скриптов обязателен пакетный режим -b, иначе toybox начнет слать escape-последовательности перерисовки и вывод превратится в кашу:
Код: Выделить всё
adb shell top -b -n 1 -m 15Потоки конкретного процесса показывает флаг -H:
Код: Выделить всё
adb shell top -H -b -n 1 -p 2841vmstat: системная картина одной строкой:
Когда нужно понять, что происходит с системой в целом, а не с отдельным процессом, удобен vmstat. Формат: задержка в секундах и число итераций, флаг -n печатает заголовок один раз:
Код: Выделить всё
adb shell vmstat -n 1 5Код: Выделить всё
procs -----------memory---------- ---swap-- -----io---- -system-- ----cpu----
r b swpd free buff cache si so bi bo in cs us sy id wa
2 0 1153024 295112 14336 2611200 0 0 12 40 4123 9870 14 9 76 1
3 0 1153024 287400 14336 2612160 0 256 0 124 6011 14250 31 12 56 1dumpsys cpuinfo: кто ел процессор:
Код: Выделить всё
adb shell dumpsys cpuinfoКод: Выделить всё
Load: 9.12 / 8.4 / 7.95
CPU usage from 412433ms to 187229ms ago (2026-06-11 14:02:11.482 to 2026-06-11 14:05:56.687):
47% 2841/com.example.game: 31% user + 15% kernel / faults: 18223 minor 12 major
18% 1287/system_server: 12% user + 5.8% kernel / faults: 9911 minor
6.1% 988/surfaceflinger: 3.7% user + 2.4% kernel
71% TOTAL: 44% user + 22% kernel + 1.2% iowait + 2.4% irq + 0.9% softirqdumpsys meminfo: память процесса:
Код: Выделить всё
adb shell dumpsys meminfo com.example.gameКод: Выделить всё
App Summary
Pss(KB) Rss(KB)
------ ------
Java Heap: 26544 33712
Native Heap: 182340 188412
Code: 48122 110233
Stack: 1980 1992
Graphics: 145200 145200
Private Other: 12244
System: 18733
TOTAL PSS: 435163 TOTAL RSS: 501480 TOTAL SWAP PSS: 6233
Objects
Views: 512 ViewRootImpl: 1
AppContexts: 8 Activities: 2Полезные вариации:
Код: Выделить всё
adb shell dumpsys meminfo -s com.example.game
adb shell dumpsys meminfo 2841
adb shell dumpsys meminfoam profile: профилировщик методов:
Когда известно, какой процесс виноват, но непонятно, какой код, подключаем профилировщик ART через Activity Manager. Процесс обязан быть отлаживаемым (android:debuggable="true" в манифесте либо userdebug-сборка системы), на релизном приложении получите ошибку SecurityException: Process not debuggable.
Код: Выделить всё
adb shell am profile start --sampling 1000 com.example.game /data/local/tmp/game.trace
adb shell am profile stop com.example.game
adb pull /data/local/tmp/game.traceПрофилирование холодного старта:
Код: Выделить всё
adb shell am start -n com.example.game/.MainActivity --start-profiler /data/local/tmp/start.trace --sampling 500
adb shell am profile stop com.example.gameСистемные трассировки: perfetto и atrace:
Профилировщик показывает только Java/ART-уровень одного процесса. Полную картину (планировщик, частоты, отрисовка кадров, binder) дает perfetto, штатный с Android 9 и включенный по умолчанию с Android 11:
Код: Выделить всё
adb shell perfetto -o /data/misc/perfetto-traces/trace.perfetto-trace -t 15s sched freq idle gfx view wm am binder_driver
adb pull /data/misc/perfetto-traces/trace.perfetto-traceКод: Выделить всё
adb shell atrace --list_categoriesКаждый вызов системного API (PackageManager, WindowManager, settings) это IPC через Binder, и вызовы в цикле или на каждом кадре заметно бьют по производительности. Встроенный трассировщик:
Код: Выделить всё
adb shell am trace-ipc start
adb shell am trace-ipc stop --dump-file /data/local/tmp/ipc.txt
adb pull /data/local/tmp/ipc.txtТемпература и частоты процессора:
Тормоза под нагрузкой часто объясняются не кодом, а троттлингом. Состояние термальной подсистемы (Android 10+):
Код: Выделить всё
adb shell dumpsys thermalserviceКод: Выделить всё
Thermal Status: 2
Current temperatures from HAL:
Temperature{mValue=42.7, mType=3, mName=SKIN, mStatus=2}
Temperature{mValue=67.1, mType=0, mName=CPU, mStatus=0}
Temperature{mValue=38.9, mType=2, mName=BATTERY, mStatus=0}Код: Выделить всё
adb shell 'for z in /sys/class/thermal/thermal_zone*; do echo $z $(cat $z/type) $(cat $z/temp); done'Текущие частоты ядер:
Код: Выделить всё
adb shell 'for c in /sys/devices/system/cpu/cpu[0-9]*; do echo $c $(cat $c/cpufreq/scaling_cur_freq 2>/dev/null); done'Код: Выделить всё
/sys/devices/system/cpu/cpu0 1804800
/sys/devices/system/cpu/cpu4 2496000
/sys/devices/system/cpu/cpu7 2841600Код: Выделить всё
adb shell 'while true; do echo "$(date +%T) skin=$(cat /sys/class/thermal/thermal_zone0/temp) cpu7=$(cat /sys/devices/system/cpu/cpu7/cpufreq/scaling_cur_freq)"; sleep 2; done'Сводка частых ошибок:
top без -b в скриптах дает мусор из escape-кодов. dumpsys cpuinfo это не реальное время, а дельта за интервал из заголовка. am profile падает на неотлаживаемых сборках и при записи в недоступный путь. perfetto на user-сборке пишет только в /data/misc/perfetto-traces. Температурные зоны врут в единицах измерения, проверяйте порядок величин. PSS между устройствами не сравнивается.
Этого набора хватает, чтобы локализовать почти любую просадку: top и vmstat показывают где, meminfo и cpuinfo показывают кто, am profile и perfetto показывают почему. В главе 22 мы обернем эти команды в скрипты для регулярных замеров, а в главе 24 встроим их в автотесты.