Linux 系统中的top 程序是一个用于显示系统运行状况的命令行程序。它提供一个显示系统运行状况的动态视图,用于显示当前由系统管理的进程(或线程)信息。
Android 系统虽然基于 Linux 内核,但是 Android 中的 top 并不等同于 Linux 系统中的 top 程序。 Android 中的 top 是 Toybox 程序的一部分。Toybox 是一个将许多常用的 Linux 命令行工具组合在一起并提供更加轻量级的实现,用于改进 Android 命令行能力的开源项目。Google 于 2015 年 Android 6.0 版本开始正式将 toybox 合并入 AOSP 中。
注:Toybox 是一个独立的开源项目,更多信息可查看项目主页:landley.net/toybox
本文介绍的是 Android 系统中集成的 Toybox 的 top 程序。
名称
top [option ...] - 实时显示活跃的任务(进程或线程)信息
描述
top 程序提供一个显示系统运行状况的实时动态视图。该视图显示了系统摘要信息、当前由系统管理的任务(进程或线程)列表。显示的系统摘要信息、任务类型、排序规则和任务数量都是用户可配置的。
top --help查看 top 程序的帮助说明;top --version或toybox --version查看 toybox 的版本信息;
操作
top 程序运行中支持以下操作:
- 退出:使用
q键 退出 程序执行,或使用传统的 中断(^c键)操作来退出; - 滚动:使用 方向键(
UP/DOWN/LEFT/RIGHT)滚动任务列表显示区域; - 刷新:使用 空格键(
SPACE)强制刷新列表数据; - 切换排序字段:使用
SHIFT+LEFT/RIGHT切换排序字段; - 切换排序规则:使用
r键对排序规则(升序、降序)进行切换;
top 程序运行时,终端界面中将显示三个部分的内容:
- 摘要区域(Summary Area)
- 标题区域(字段/列)(Fields/Columns Header)
- 任务区域(Task Area)
内存类型
物理内存 指设备上安装的内存条,是硬件中实际存在的内存单元。物理内存是有限且珍贵的,为了对物理内存实现更加高效合理的利用,操作系统提供了虚拟内存的概念。虚拟内存 是操作系统中的一个抽象概念,它为每个应用提供了独立的、连续的内存地址空间。
虚拟内存比物理内存大的多,几乎是一种无限的资源,使得程序可以访问更多的内存空间。虚拟内存并不完全存在于内存空间中,部分虚拟内存可能存在于内存交换区或持久化存储器(如硬盘)中。虚拟内存的存在具备以下优点:
- 抽象,Abstractin:不受物理内存地址的限制和影响
- 隔离,Isolation:每个进程都拥有独立的、连续的内存地址空间
- 共享,Sharing:单个内存映射可以满足多个内存需求
- 灵活,Flexibility,可以为文件分配虚拟内存地址
注:Android 系统中的内存设计请参见:Android Developers - Overview of memory management
物理内存和虚拟内存都采用内存分页进行管理,每个页面为 4KB 的内存(Android 15 开始为 16KB,请参见:Android Developers - Support 16 KB page sizes)。
共享内存,指系统中使用了相同服务或库的多个不同应用,共享的部分内存页面。
衡量应用内存占用时通常有以下指标:
- VSS = Virtual Memory Size,虚拟内存大小:任务可使用的全部(共享和非共享)虚拟内存的大小,含已申请但未使用的内存大小
- RSS = Resident Set Size,常驻内存大小:应用实际使用的全部(共享和非共享)内存大小,不含已申请但未使用的内存大小
- PSS = Proportional Set Size,按比例分摊的内存大小:应用使用的非共享内存的数量加上共享页面的均匀分摊数量(例如,如果三个进程共享 3 MB,每个进程的 PSS 中各包含 1 MB 的共享内存用量)
- USS = Unique Set Size,独占内存大小:应用使用的非共享内存大小
字段
top 程序显示的任务列表的信息,任务信息具备以下字段。
PID, Process Id
进程号,查看进程信息时显示进程的进程号
TID, Thread Id
线程号,查看线程信息时显示线程的线程号
USER, User
用户名,任务所有者的有效用户名
PR, Priority
优先级,任务的调度优先级。值越小优先级越高。
NI,Nice Value
Nice 值,同组任务的调度优先级。值越小优先级越高。
VIRT, Virtual Memory Size
虚拟内存大小,单位:Kib。任务所使用的虚拟内存的总的大小。当显示线程时,该值实际上显示的是线程所在进程的总虚拟内存。
RES, Resident Memory Size
驻留内存大小,单位:Kib。
SHR, Shared Memory Size
共享内存大小,单位:Kib。
S, State
任务当前状态,取值如下:
- R = 运行中
- S = 休眠中
- D = 不可中断
- Z = 僵死
- T = 停止
%CPU
CPU 使用率,top 程序刷新间隔时间段内,该任务所占用 CPU 时长与 CPU 总时长的百分比表示。对于多核处理器而言,该值有可能会超过 100%。
%MEN
内存使用率,任务当前所占用的物理内存百分比。当显示线程时,该值实际上显示的是线程所在进程的内存占用。
TIME+
任务自启动以来所使用的 CPU 累计时长,精度为一秒的百分之一(即厘秒)。显示格式为 minutes:seconds.hundredths。例如:
0:00.27 即 0 分钟,0 秒钟,27 厘秒
100:00.27 即 100 分钟,0 秒钟,27 厘秒
100:00.00 即 100 分钟,0 秒钟, 0 厘秒
100:00 即 100 分钟,0 秒钟, 0 厘秒
CMDLINE
显示用于启动任务的命令行或关联程序的名称,通常为进程名或线程名。
对于命令行程序进程而言,即启动时的完整命令字参数。例如使用 top -h 启动 top 程序,则其进程的 CMDLINE 为 “top -h”。
对于安卓应用进程而言,默认情况下为应用包名。即 AndroidManifest.xml 中的 android:process 的值。
一切进程的 CMDLINE 可以通过访问 proc/<pid>/cmdline 文件获取,请将 <pid> 替换为相应的进程号。
对于线程而言,CMDLINE 即线程的线程名,可以通过 Thread#setName 进行修改。
选项
top [-Hhbq] [-k FIELD,] [-o FIELD,] [-s SORT] [-n NUMBER] [-m LINES] [-d SECONDS] [-p PID,] [-u USER,]
-H 指定显示线程信息
指示 top 程序在任务区域独立显示线程信息。如果没有此选项,任务区域默认将以进程为最小单位进行条目显示。
-h 使用图表代替文本摘要
指示 top 程序在摘要区域以图表的形式代替文本形式显示摘要信息。
-k 指定默认的排序字段
// TODO: 待阐述,原文描述为“Fallback sort FIELDS (default -S,-%CPU,-ETIME,-PID)”,没搞懂
-o 显示指定字段
指示 top 程序显示的任务字段,以及字段的顺序。多个字段之间使用英文逗号 , 进行分隔。默认情况下使用 PID,USER,PR,NI,VIRT,RES,SHR,S,%CPU,%MEM,TIME+,CMDLINE 的字段组合进行显示。
-O 添加指定字段
向 top 程序添加需要显示的字段及顺序,用于替换默认情况下的 PR,NI,VIRT,RES,SHR,S 字段组合。与 -o 相比具备以下区别:
- 使用
-O时依然会保留开头的PID,USER字段,以及结尾的%CPU,%MEM,TIME+,CMDLINE字段;而-o会替换所有的参数。 - 使用
-O时将默认使用第 3 个字段进行排序,除掉开头的PID,USER字段,即默认使用-O传递的第一个参数进行排序。
-s 根据指定字段排序
指示 top 程序默认根据指定的字段进行排序。默认值为 9,即默认使用第 9 列字段进行排序。取值范围为 1-X,X 为您传入的需要显示的字段列数目。
-b 批处理模式(无终端)
指示 top 程序使用批处理模式进行输出。此时将没有终端界面,无法使用退出、滚动、刷新、排序等功能。此时退出 top 程序需要使用传统的 中断(^c 键)操作。
-d 指定列表更新间隔
指示 top 程序显示的任务数据默认的刷新间隔时间,单位:秒。默认值为 3。
-m 任务区域最大显示的条目数
指示 top 程序任务区域列表最大显示的条目数。如果没有此选项,任务区域将根据终端窗口的高度显示合适的条目数。
-n 指定刷新指定次数后退出
指示 top 程序在刷新指定次数的数据后退出。
-p 显示指定进程的任务信息
指示 top 程序仅显示指定进程的任务信息,即根据进程号进行数据过滤。当需要显示多个进程的任务数据时,使用英文逗号 , 进行分隔。
-u 显示指定用户的任务信息
指示 top 程序仅显示指定,即根据用户进行数据过滤,当需要显示多个用户的任务数据时,使用英文逗号 , 进行分隔。
-q 静默模式
指示 top 程序使用静默模式运行,即不输出 摘要信息 及 标题信息,仅输出列表数据。
参考资料: