dumpsys介绍

请尊重原创版权,转载注明出处。

1. 概要

dumpsys是Android提供的系统工具,可以用来查看所有系统服务的信息。

在命令行输入如下命令,就可以罗列出当前所有的系统服务名:

$ adb shell dumpsys -l
Currently running services:
  ...
  SurfaceFlinger
  ...
  activity
  alarm
  ...
  battery
  batterystats
  ...
  meminfo
  ...
  window

如果dumpsys不追加任何参数,则会输出所有系统服务的详细信息,输出的内容是非常多的。实际解决具体问题时,我们通常只关注一些特定系统服务的输出, 只需要将服务名作为dumpsys命令的参数,就可以只输出特定服务的信息。譬如要输出磁盘使用的统计信息,则可以将diskstats这个系统服务名作为参数:

$ adb shell dumpsys diskstats
Latency: 0ms [512B Data Write]
Data-Free: 6589272K / 12258876K total = 53% free
Cache-Free: 337720K / 420552K total = 80% free
System-Free: 306024K / 1523568K total = 20% free

2. 工作原理

dumpsys是Android上的一个二进制程序, 在命令行输出adb shell dumpsys xx命令,会通过adbdumpsys xx发送到移动设备执行 (adb的工作原理可以参见adb介绍一文), 收到dumpsys xx指令后,dumpsys这个二进制程序就开始工作了,dumpsys本身只提供一个输出框架,具体的输出内容还是交由实际的系统服务完成。

下图是dumpsys的工作原理:

dumpsys工作原理

2.1 dumpsys的代码逻辑

dumpsysframeworks/native/cmds/dumpsys/dumpsys.cpp这个文件中编译得到。 我们截取该文件主要的代码片段来分析一下:

int main(int argc, char* const argv[])
{
    ...
    // 1. 首先获取 servicemanager
    sp<IServiceManager> sm = defaultServiceManager();
    ...
    // 2. 进行命令行参数解析
    bool showListOnly = false;
    if ((argc == 2) && (strcmp(argv[1], "-l") == 0)) {
        // 2.1 当参数仅为 "-l" 时,设置只罗列出所有的服务名
        showListOnly = true;
    }
    if ((argc == 1) || showListOnly) {
        // 2.2 当不带任何参数时,则附加 "-a" 参数,表示输出所有系统服务信息
        services = sm->listServices();
        services.sort(sort_func);
        args.add(String16("-a"));
    } else {
        // 2.3 当带了一个参数时,表示仅输出指定的系统服务信息
        services.add(String16(argv[1]));
        for (int i=2; i<argc; i++) {
            args.add(String16(argv[i]));
        }
    }

    // 3. 罗列出services这个数组中的服务名称,到这一步为止,都还只是在dumpsys本身的逻辑中转悠
    const size_t N = services.size();
    if (N > 1) {
        aout << "Currently running services:" << endl;    
        for (size_t i=0; i<N; i++) {
            sp<IBinder> service = sm->checkService(services[i]);
            if (service != NULL) {
                aout << "  " << services[i] << endl;
            }
        }
    }
    if (showListOnly) {
        return 0;
    }

    // 4. 输出services这个数组中所包含系统服务的详细信息
    for (size_t i=0; i<N; i++) {
        sp<IBinder> service = sm->checkService(services[i]);
        if (service != NULL) {
            ...
            // 4.1 调用service的dump方法,来输出service的具体信息
            int err = service->dump(STDOUT_FILENO, args);
            ...
        }
        ...
    }
    return 0;
}

代码逻辑并不复杂,按照如下逻辑执行:

  1. 获取servicemanager,所有的系统服务都会向servicemanager注册
  2. 进行命令行参数解析,根据参数的不同设置后续的执行指令序列
  3. 简单的罗列了一下需要输出的系统服务名称
  4. 真正完成系统服务详细信息的输出

关键在第4步的实现,调用具体系统服务的dump()方法。

2.2 系统服务的dump方法

Android中,所有的系统服务都是Binder的子类,Binder作为一个抽象的概念,用来描述一个远程对象, 这里有几个基础知识:

  • Android中的系统服务,譬如ActivityManagerService, PackageManagerService, BatteryStatsService等都是运行在system_server这个进程中, 在Android启动的时候,就会按照系统服务的重要性,按序来启动这些的系统服务,它们作为服务端,为整个Android系统提供服务支撑。

  • Android中的应用程序是运行在独立的进程中的,如过某个应用程序需要使用系统服务,则需要发起跨进程调用(Remote Procedure Call, RPC),应用程序将作为客户端, 与系统服务进行数据交换。

  • Android上实现RPC的机制就是Binder,当客户端获取到Binder时,就可以理解为客户端跟系统服务建立绑定关系,这时,Binder就代表了远程系统服务。 实际的系统服务,都是Binder的子类,需要实现Binder定义的抽象方法,其中Binder.dump()这个方法就是专门为输出系统服务的信息而生。

  • Binder.dump()这个方法的实现,完全由实际的系统服务来控制,可以附加访问权限,可以输出任何信息,甚至可以为空实现。如果某个系统服务的dump()方法 为空实现,那么使用dumpsys输出这个信息服务的信息就为空。

DiskStatsService.dump()这个方法为例,在命令行输出adb shell dumpsys diskstats,最终的实现就落到该方法中:

protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
    // 1. 权限检查
    mContext.enforceCallingOrSelfPermission(android.Manifest.permission.DUMP, TAG);

    // 2. 生成一个大小为512B的临时文件
    byte[] junk = new byte[512];
    for (int i = 0; i < junk.length; i++) junk[i] = (byte) i;  // Write nonzero bytes
    File tmp = new File(Environment.getDataDirectory(), "system/perftest.tmp");

    // 3. 将512B的临时文件写入磁盘,目的是为了快速的测试写磁盘的延迟
    long before = SystemClock.uptimeMillis();
    ...
    fos = new FileOutputStream(tmp);
    fos.write(junk);
    ...
    long after = SystemClock.uptimeMillis();
    ...
    pw.print("Latency: ");
    pw.print(after - before);
    pw.println("ms [512B Data Write]");
    ...
    // 4. 输出Data, Cache和System这几个分区的磁盘使用信息
    reportFreeSpace(Environment.getDataDirectory(), "Data", pw);
    reportFreeSpace(Environment.getDownloadCacheDirectory(), "Cache", pw);
    reportFreeSpace(new File("/system"), "System", pw);
    ....
}

3. 解析dumpsys输出

dumpsys输出内容的理解需要有相关领域的知识,能够理解这些日志,对Android性能调优、Bug调试都有很大的帮助,这也是一个Android系统开发人员的必备技能。

笔者分析了常见系统服务的dumpsys日志输出:

目前,已经有一些工具,对dumpsys的输出内容进行解析,并作图形化的展示,便于系统开发人员分析问题。例如:

<think>我们正在处理用户关于dumpsysSurfaceFlinger的查询。用户想查看SurfaceFlinger的相关信息或调试输出。根据引用内容,dumpsysSurfaceFlinger是一个用于获取系统图层信息的命令。用户需求明确:执行dumpsysSurfaceFlinger命令来获取信息。根据引用[1]和引用[3]:-通过`dumpsysSurfaceFlinger`可以查看surfaceFlinger相关系统信息,比如layer信息,hwc合成信息,buffer信息等。-引用[3]中还提到`dumpsysSurfaceFlinger`可以查看系统图层,并可以看到Activity栈。因此,回答应该指导用户如何使用该命令,并解释输出的大致内容。由于用户可能在使用命令时遇到权限问题(如adbshell),我们可以提及这一点。同时,根据用户提供的引用,我们可以补充一些相关命令,比如查看当前顶部Activity(因为SurfaceFlinger也涉及窗口显示):-`dumpsyswindowwindows|grep-E"mCurrentFocus|mFocusedApp"`但是用户问题仅针对SurfaceFlinger,所以我们主要围绕它。另外,引用[3]提到可以用`dumpsys-l`查看所有服务,如果用户想了解其他服务,也可以提及,但以SurfaceFlinger为主。我们按照系统级指令要求:1.行内数学表达式使用$...$(但此处基本没有数学表达式,可以忽略)2.独立公式用$$...$$(同样,这里不需要)3.LaTeX语法正确(无需)4.中文回答5.生成相关问题由于用户问题是一个具体操作,回答应简洁明了,步骤化。注意:引用标识添加在参考了引用内容的地方。回答结构:1.介绍dumpsysSurfaceFlinger命令的作用。2.说明如何使用该命令(包括连接设备、使用adbshell等)。3.解释输出内容包含哪些重要信息。4.补充可能的相关命令(如需要)。5.添加相关问题。引用标识:-在提到可以通过该命令获取layer信息、hwc信息等时,引用[^1]。-在提到查看Activity栈时,引用[^3]。-其他引用内容视情况。最后生成相关问题。</think> 要查看 `SurfaceFlinger` 的调试信息,请按以下步骤操作(需连接 Android 设备或模拟器): ### 1. **执行命令** ```bash adb shell dumpsys SurfaceFlinger ``` 这会输出 `SurfaceFlinger` 的完整状态信息,包括: - **图层信息 (Layers)**:所有活动图层的层级、尺寸、合成状态[^1] - **HWC 合成细节**:硬件合成器 (Hardware Composer) 的合成策略和资源占用[^1] - **Buffer 状态**:图形缓冲区的分配/释放记录(如队列长度、帧延迟)[^1] - **显示配置**:当前屏幕分辨率、刷新率、HDR 支持等[^3] - **性能统计**:帧率(FPS)、丢帧情况(Jank)[^1] ### 2. **过滤关键信息** 通过 `grep` 快速定位: ```bash # 查看活动图层 adb shell dumpsys SurfaceFlinger | grep "Active layers" # 检查帧率 adb shell dumpsys SurfaceFlinger | grep "FPS" # 查看屏幕配置 adb shell dumpsys SurfaceFlinger | grep "DisplayConfig" ``` ### 3. **关联调试技巧** - **查看顶层窗口**(结合 `WindowManager`): ```bash adb shell dumpsys window windows | grep "mCurrentFocus" ``` 可确认当前焦点窗口是否被 `SurfaceFlinger` 正常渲染[^3]。 - **监控图形性能**: ```bash adb shell dumpsys gfxinfo <package_name> ``` 分析特定应用的帧生成耗时(如 `Choreographer#doFrame`)[^2]。 ### 4. **注意事项** - 需开启 **USB 调试**(开发者模式) - 部分新功能(如游戏模式/可变刷新率)需 Android 12+ - 若输出为空,检查服务状态:`adb shell service check SurfaceFlinger`[^3] --- **
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值