当前位置: 首页 > news >正文

【Android】关于binder_calls_stats服务

Android 9上有了binder_calls_stats服务,提供了java层的binder统计,

Android中的Binder Call Stats(Binder调用统计)是一项用于监控和记录Android系统中Binder通信的统计信息的功能。Binder是Android中的一种进程间通信(IPC)机制,用于在不同的进程之间传递数据和调用方法。

Binder Call Stats提供了有关Binder调用的性能和统计数据,帮助开发人员分析和优化系统的性能。它可以提供以下信息:

  1. Binder调用次数:统计Binder方法被调用的次数,包括进程间的远程调用和本地调用。

  2. Binder调用耗时:记录Binder方法的执行时间,包括调用传输数据的时间和远程进程执行方法的时间。

  3. Binder调用堆栈跟踪:跟踪Binder调用的堆栈信息,可以帮助开发人员确定调用路径和定位性能瓶颈。

  4. Binder调用的进程和线程信息:记录Binder调用发生的进程和线程信息,有助于分析系统中不同组件之间的通信情况。

通过分析Binder Call Stats,开发人员可以识别性能瓶颈、优化IPC通信,改进应用程序的响应性能和资源利用率。

要收集Binder Call Stats,开发人员可以使用Android系统提供的工具和API,例如使用adb shell命令进行监测,或者使用Trace类和Debug类提供的方法进行手动埋点和记录统计数据。

需要注意的是,Binder Call Stats对于普通应用程序开发人员来说可能并不常用,主要用于系统级开发和性能调优。

public class BinderCallsStatsService extends Binder {
30
31    private static final String TAG = "BinderCallsStatsService";
32
33    private static final String PERSIST_SYS_BINDER_CALLS_DETAILED_TRACKING
34            = "persist.sys.binder_calls_detailed_tracking";
35
36    public static void start() {
37        BinderCallsStatsService service = new BinderCallsStatsService();
38        ServiceManager.addService("binder_calls_stats", service);
39        boolean detailedTrackingEnabled = SystemProperties.getBoolean(
40                PERSIST_SYS_BINDER_CALLS_DETAILED_TRACKING, false);
41
42        if (detailedTrackingEnabled) {
43            Slog.i(TAG, "Enabled CPU usage tracking for binder calls. Controlled by "
44                    + PERSIST_SYS_BINDER_CALLS_DETAILED_TRACKING
45                    + " or via dumpsys binder_calls_stats --enable-detailed-tracking");
46            BinderCallsStats.getInstance().setDetailedTracking(true);
47        }
48    }
49
50    public static void reset() {
51        Slog.i(TAG, "Resetting stats");
52        BinderCallsStats.getInstance().reset();
53    }
54
55    @Override
56    protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
57        if (args != null) {
58            for (final String arg : args) {
59                if ("-a".equals(arg)) {
60                    // We currently dump all information by default
61                    continue;
62                } else if ("--reset".equals(arg)) {
63                    reset();
64                    pw.println("binder_calls_stats reset.");
65                    return;
66                } else if ("--enable-detailed-tracking".equals(arg)) {
67                    SystemProperties.set(PERSIST_SYS_BINDER_CALLS_DETAILED_TRACKING, "1");
68                    BinderCallsStats.getInstance().setDetailedTracking(true);
69                    pw.println("Detailed tracking enabled");
70                    return;
71                } else if ("--disable-detailed-tracking".equals(arg)) {
72                    SystemProperties.set(PERSIST_SYS_BINDER_CALLS_DETAILED_TRACKING, "");
73                    BinderCallsStats.getInstance().setDetailedTracking(false);
74                    pw.println("Detailed tracking disabled");
75                    return;
76                } else if ("-h".equals(arg)) {
77                    pw.println("binder_calls_stats commands:");
78                    pw.println("  --reset: Reset stats");
79                    pw.println("  --enable-detailed-tracking: Enables detailed tracking");
80                    pw.println("  --disable-detailed-tracking: Disables detailed tracking");
81                    return;
82                } else {
83                    pw.println("Unknown option: " + arg);
84                }
85            }
86        }
87        BinderCallsStats.getInstance().dump(pw);
88    }
89}
90

可以看到,是通过BinderCallsStats来进行统计的,而BinderCallsStats通过在Java层Binder对象中的使用来进行记录,

frameworks/base/core/java/android/os/Binder.java

    // Entry point from android_util_Binder.cpp's onTransact
714    private boolean execTransact(int code, long dataObj, long replyObj,
715            int flags) {
716        BinderCallsStats binderCallsStats = BinderCallsStats.getInstance();
717        BinderCallsStats.CallSession callSession = binderCallsStats.callStarted(this, code);
718        Parcel data = Parcel.obtain(dataObj);
719        Parcel reply = Parcel.obtain(replyObj);
720        // theoretically, we should call transact, which will call onTransact,
721        // but all that does is rewind it, and we just got these from an IPC,
722        // so we'll just call it directly.
723        boolean res;
724        // Log any exceptions as warnings, don't silently suppress them.
725        // If the call was FLAG_ONEWAY then these exceptions disappear into the ether.
726        final boolean tracingEnabled = Binder.isTracingEnabled();
727        try {
728            if (tracingEnabled) {
729                Trace.traceBegin(Trace.TRACE_TAG_ALWAYS, getClass().getName() + ":" + code);
730            }
731            res = onTransact(code, data, reply, flags);
732        } catch (RemoteException|RuntimeException e) {
733            if (LOG_RUNTIME_EXCEPTION) {
734                Log.w(TAG, "Caught a RuntimeException from the binder stub implementation.", e);
735            }
736            if ((flags & FLAG_ONEWAY) != 0) {
737                if (e instanceof RemoteException) {
738                    Log.w(TAG, "Binder call failed.", e);
739                } else {
740                    Log.w(TAG, "Caught a RuntimeException from the binder stub implementation.", e);
741                }
742            } else {
743                reply.setDataPosition(0);
744                reply.writeException(e);
745            }
746            res = true;
747        } finally {
748            if (tracingEnabled) {
749                Trace.traceEnd(Trace.TRACE_TAG_ALWAYS);
750            }
751        }
752        checkParcel(this, code, reply, "Unreasonably large binder reply buffer");
753        reply.recycle();
754        data.recycle();
755
756        // Just in case -- we are done with the IPC, so there should be no more strict
757        // mode violations that have gathered for this thread.  Either they have been
758        // parceled and are now in transport off to the caller, or we are returning back
759        // to the main transaction loop to wait for another incoming transaction.  Either
760        // way, strict mode begone!
761        StrictMode.clearGatheredViolations();
762        binderCallsStats.callEnded(callSession);
763
764        return res;
765    }

而更加底层的统计,可以查看/dev/binder 里面的binder_status

binder_status是Android系统中的一个特殊文件,用于提供有关Binder驱动程序状态的信息。该文件位于/proc/binder/status路径下,只有在具有root权限或系统签名的设备上才能访问。

binder_status文件提供了有关Binder驱动程序的各种统计和状态信息,包括:

  1. 总体信息:包括Binder线程池的大小、当前正在等待的线程数等。

  2. 事务计数:显示有关Binder事务(包括进程间通信和本地调用)的计数信息,例如总事务数、活动事务数、等待事务数等。

  3. 线程信息:列出了所有活动的Binder线程的详细信息,包括线程ID、所属进程、线程状态等。

  4. 回收信息:显示已回收的Binder对象和节点的数量。

通过读取binder_status文件,您可以获取有关Binder驱动程序的运行状况和性能指标的信息,这对于调试和分析Binder相关问题非常有用。然而,由于它提供的信息非常底层和详细,需要一定的理解和背景知识才能正确解读和使用这些数据。

请注意,访问binder_status文件需要root权限或系统签名,并且在正常情况下,一般用户不需要直接访问或操作该文件。

相关文章:

【Android】关于binder_calls_stats服务

Android 9上有了binder_calls_stats服务,提供了java层的binder统计, Android中的Binder Call Stats(Binder调用统计)是一项用于监控和记录Android系统中Binder通信的统计信息的功能。Binder是Android中的一种进程间通信&#xff…...

给前端返回http链接,由于浏览器缓存不能获取到最新资源怎么办?

1、问题描述 今天在工作中接到这样一个需求,接收前端的图片文件并上传到远程,将原有图片覆盖并返回一个http链接以供前端展示。用户使用后反馈没有修改成功,上了远程拉图片发现已经修改了,但是用户浏览器还是老的图片。排查原因是…...

【Java Web】检查用户登录状态,防止用户访问到非法页面

使用拦截器 在方法前标注自定义注解拦截所有请求&#xff0c;只处理带有该注解的方法 自定义注解&#xff1a; 常用元注解&#xff1a;Target, Rentention, Document, Inherited如何读取注解&#xff1a; - Method.getDeclaredAnnotations() - Method.getAnnotaion(Class<T&…...

数学建模——校园供水系统智能管理

import pandas as pd data1pd.read_excel("C://Users//JJH//Desktop//E//附件_一季度.xlsx") data2pd.read_excel("C://Users//JJH//Desktop//E//附件_二季度.xlsx") data3pd.read_excel("C://Users//JJH//Desktop//E//附件_三季度.xlsx") data4…...

分布式集群——搭建Hadoop环境以及相关的Hadoop介绍

系列文章目录 分布式集群——jdk配置与zookeeper环境搭建 分布式集群——搭建Hadoop环境以及相关的Hadoop介绍 文章目录 前言 一 hadoop的相关概念 1.1 Hadoop概念 补充&#xff1a;块的存储 1.2 HDFS是什么 1.3 三种节点的功能 I、NameNode节点 II、fsimage与edits…...

Python的os.walk()函数使用案例

在Python中&#xff0c;os模块是一个非常实用的工具&#xff0c;它可以让我们与操作系统进行交互&#xff0c;操作文件和目录。在本文中&#xff0c;我们将详细介绍os模块中的遍历文件功能&#xff0c;并通过具体案例和使用场景来解释。 首先&#xff0c;导入os模块。在Pytho…...

学习JAVA打卡第四十五天

StringBuffer类 StringBuffer对象 String对象的字符序列是不可修改的&#xff0c;也就是说&#xff0c;String对象的字符序列的字符不能被修改、删除&#xff0c;即String对象的实体是不可以再发生变化&#xff0c;例如&#xff1a;对于 StringBuffer有三个构造方法&#xff…...

创建K8s pod Webhook

目录 1.前提条件 2.开始创建核心组件Pod的Webhook 2.1.什么是Webhook 2.2.在本地k8s集群安装cert-manager 2.3.创建一个空的文件夹 2.4. 生成工程框架 2.5. 生成核心组件Pod的API 2.6.生成Webhook 2.7.开始实现Webhook相关代码 2.7.1.修改相关配置 2.7.2.修改代码 2…...

抓包-要抓取Spring Boot应用程序的请求

要抓取Spring Boot应用程序的请求&#xff0c;可以按照以下步骤进行操作&#xff1a; 1. 确保你已经按照之前提到的方法设置了Charles代理&#xff0c;并在Charles的SSL代理设置中添加了Spring Boot应用程序的域名。 2. 在Spring Boot应用程序的代码中&#xff0c;添加以下配…...

jmeter+nmon+crontab简单的执行接口定时压测

一、概述 临时接到任务要对系统的接口进行压测&#xff0c;上面的要求就是&#xff1a;压测&#xff0c;并发2000 在不熟悉系统的情况下&#xff0c;按目前的需求&#xff0c;需要做的步骤&#xff1a; 需要有接口脚本需要能监控系统性能需要能定时执行脚本 二、观察 >针…...

ZooKeeper基础命令和Java客户端操作

1、zkCli的常用命令操作 &#xff08;1&#xff09;Help &#xff08;2&#xff09;ls 使用 ls 命令来查看当前znode中所包含的内容 &#xff08;3&#xff09;ls2查看当前节点数据并能看到更新次数等数据 &#xff08;4&#xff09;stat查看节点状态 &#xff08;5&#xf…...

【数据分享】2000-2020年全球人类足迹数据(无需转发\免费获取)

人类足迹(Human Footprint)是生态过程和自然景观变化对生态环境造成的压力&#xff0c;是世界各国对生物多样性和生态保护的关注重点。那如何才能获取长时间跨度的人类足迹时空数据呢&#xff1f; 之前我们分享了来自于中国农业大学土地科学与技术学院的城市环境监测及建模&am…...

基于机器学习的fNIRS信号质量控制方法

摘要 尽管功能性近红外光谱(fNIRS)在神经系统研究中的应用越来越广泛&#xff0c;但fNIRS信号处理仍未标准化&#xff0c;并且受到经验和手动操作的高度影响。在任何信号处理过程的开始阶段&#xff0c;信号质量控制(SQC)对于防止错误和不可靠结果至关重要。在fNIRS分析中&…...

分布式锁的三种实现方式是什么?

分布式锁三种实现方式&#xff1a; 基于数据库实现分布式锁&#xff1b;基于缓存&#xff08;Redis等&#xff09;实现分布式锁&#xff1b;基于Zookeeper实现分布式锁&#xff1b; 一&#xff0c; 基于数据库实现分布式锁 悲观锁 利用select … where … for update 排他锁…...

华为云软件精英实战营——感受软件改变世界,享受Coding乐趣

机器人已经在诸多领域显现出巨大的商业价值&#xff0c;华为云计算致力于以云助端的方式为机器人产业带来全新机会 如果您是开发爱好者&#xff0c;想了解华为云&#xff0c;想和其他自由开发者交流经验&#xff1b; 如果您是学生&#xff0c;想和正在从事软件开发行业的大佬…...

贪心算法总结篇

文章转自代码随想录 贪心算法总结篇 我刚刚开始讲解贪心系列的时候就说了&#xff0c;贪心系列并不打算严格的从简单到困难这么个顺序来讲解。 因为贪心的简单题可能往往过于简单甚至感觉不到贪心&#xff0c;如果我连续几天讲解简单的贪心&#xff0c;估计录友们一定会不耐…...

ICCV 2023 | 港中文MMLab: 多帧光流估计模型VideoFlow,首次实现亚像素级别误差

本文提出了一个多帧光流估计模型 VideoFlow&#xff0c;旨在充分挖掘视频中的时序信息和运动规律&#xff0c;避免当前主流方法只以两帧图片作为输入而面临的信息瓶颈&#xff0c;显著提升了光流估计的性能。 在公开的 Sintel Bechmark 上&#xff0c;VideoFlow 在 Clean 和 Fi…...

【python爬虫】—图片爬取

图片爬取 需求分析Python实现 需求分析 从https://pic.netbian.com/4kfengjing/网站爬取图片&#xff0c;并保存 Python实现 获取待爬取网页 def get_htmls(pageslist(range(2, 5))):"""获取待爬取网页"""pages_list []for page in pages:u…...

自动化运维工具—Ansible

一、Ansible概述1.1 Ansible是什么1.2 Ansible的特性1.3 Ansible的特点1.4 Ansible数据流向 二、Ansible 环境安装部署三、Ansible 命令行模块&#xff08;1&#xff09;command 模块&#xff08;2&#xff09;shell 模块&#xff08;3&#xff09;cron 模块&#xff08;4&…...

uniapp 安卓平台签名证书(.keystore)生成

安装JRE环境 下载jre安装包&#xff1a;https://www.oracle.com/java/technologies/downloads/#java8安装jre安装包时&#xff0c;记录安装目录(例:C:\Program Files\Java\jdk-20)打开命令行&#xff08;cmd&#xff09;&#xff0c;将JRE安装路径添加到系统环境变量 d: se…...

MongoDB学习和应用(高效的非关系型数据库)

一丶 MongoDB简介 对于社交类软件的功能&#xff0c;我们需要对它的功能特点进行分析&#xff1a; 数据量会随着用户数增大而增大读多写少价值较低非好友看不到其动态信息地理位置的查询… 针对以上特点进行分析各大存储工具&#xff1a; mysql&#xff1a;关系型数据库&am…...

Go 语言接口详解

Go 语言接口详解 核心概念 接口定义 在 Go 语言中&#xff0c;接口是一种抽象类型&#xff0c;它定义了一组方法的集合&#xff1a; // 定义接口 type Shape interface {Area() float64Perimeter() float64 } 接口实现 Go 接口的实现是隐式的&#xff1a; // 矩形结构体…...

ESP32 I2S音频总线学习笔记(四): INMP441采集音频并实时播放

简介 前面两期文章我们介绍了I2S的读取和写入&#xff0c;一个是通过INMP441麦克风模块采集音频&#xff0c;一个是通过PCM5102A模块播放音频&#xff0c;那如果我们将两者结合起来&#xff0c;将麦克风采集到的音频通过PCM5102A播放&#xff0c;是不是就可以做一个扩音器了呢…...

【JavaSE】绘图与事件入门学习笔记

-Java绘图坐标体系 坐标体系-介绍 坐标原点位于左上角&#xff0c;以像素为单位。 在Java坐标系中,第一个是x坐标,表示当前位置为水平方向&#xff0c;距离坐标原点x个像素;第二个是y坐标&#xff0c;表示当前位置为垂直方向&#xff0c;距离坐标原点y个像素。 坐标体系-像素 …...

如何在最短时间内提升打ctf(web)的水平?

刚刚刷完2遍 bugku 的 web 题&#xff0c;前来答题。 每个人对刷题理解是不同&#xff0c;有的人是看了writeup就等于刷了&#xff0c;有的人是收藏了writeup就等于刷了&#xff0c;有的人是跟着writeup做了一遍就等于刷了&#xff0c;还有的人是独立思考做了一遍就等于刷了。…...

Java线上CPU飙高问题排查全指南

一、引言 在Java应用的线上运行环境中&#xff0c;CPU飙高是一个常见且棘手的性能问题。当系统出现CPU飙高时&#xff0c;通常会导致应用响应缓慢&#xff0c;甚至服务不可用&#xff0c;严重影响用户体验和业务运行。因此&#xff0c;掌握一套科学有效的CPU飙高问题排查方法&…...

jmeter聚合报告中参数详解

sample、average、min、max、90%line、95%line,99%line、Error错误率、吞吐量Thoughput、KB/sec每秒传输的数据量 sample&#xff08;样本数&#xff09; 表示测试中发送的请求数量&#xff0c;即测试执行了多少次请求。 单位&#xff0c;以个或者次数表示。 示例&#xff1a;…...

Ubuntu系统复制(U盘-电脑硬盘)

所需环境 电脑自带硬盘&#xff1a;1块 (1T) U盘1&#xff1a;Ubuntu系统引导盘&#xff08;用于“U盘2”复制到“电脑自带硬盘”&#xff09; U盘2&#xff1a;Ubuntu系统盘&#xff08;1T&#xff0c;用于被复制&#xff09; &#xff01;&#xff01;&#xff01;建议“电脑…...

c# 局部函数 定义、功能与示例

C# 局部函数&#xff1a;定义、功能与示例 1. 定义与功能 局部函数&#xff08;Local Function&#xff09;是嵌套在另一个方法内部的私有方法&#xff0c;仅在包含它的方法内可见。 • 作用&#xff1a;封装仅用于当前方法的逻辑&#xff0c;避免污染类作用域&#xff0c;提升…...

图解JavaScript原型:原型链及其分析 | JavaScript图解

​​ 忽略该图的细节&#xff08;如内存地址值没有用二进制&#xff09; 以下是对该图进一步的理解和总结 1. JS 对象概念的辨析 对象是什么&#xff1a;保存在堆中一块区域&#xff0c;同时在栈中有一块区域保存其在堆中的地址&#xff08;也就是我们通常说的该变量指向谁&…...