当前位置: 首页 > 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…...

React Native 开发环境搭建(全平台详解)

React Native 开发环境搭建&#xff08;全平台详解&#xff09; 在开始使用 React Native 开发移动应用之前&#xff0c;正确设置开发环境是至关重要的一步。本文将为你提供一份全面的指南&#xff0c;涵盖 macOS 和 Windows 平台的配置步骤&#xff0c;如何在 Android 和 iOS…...

centos 7 部署awstats 网站访问检测

一、基础环境准备&#xff08;两种安装方式都要做&#xff09; bash # 安装必要依赖 yum install -y httpd perl mod_perl perl-Time-HiRes perl-DateTime systemctl enable httpd # 设置 Apache 开机自启 systemctl start httpd # 启动 Apache二、安装 AWStats&#xff0…...

Map相关知识

数据结构 二叉树 二叉树&#xff0c;顾名思义&#xff0c;每个节点最多有两个“叉”&#xff0c;也就是两个子节点&#xff0c;分别是左子 节点和右子节点。不过&#xff0c;二叉树并不要求每个节点都有两个子节点&#xff0c;有的节点只 有左子节点&#xff0c;有的节点只有…...

GC1808高性能24位立体声音频ADC芯片解析

1. 芯片概述 GC1808是一款24位立体声音频模数转换器&#xff08;ADC&#xff09;&#xff0c;支持8kHz~96kHz采样率&#xff0c;集成Δ-Σ调制器、数字抗混叠滤波器和高通滤波器&#xff0c;适用于高保真音频采集场景。 2. 核心特性 高精度&#xff1a;24位分辨率&#xff0c…...

html-<abbr> 缩写或首字母缩略词

定义与作用 <abbr> 标签用于表示缩写或首字母缩略词&#xff0c;它可以帮助用户更好地理解缩写的含义&#xff0c;尤其是对于那些不熟悉该缩写的用户。 title 属性的内容提供了缩写的详细说明。当用户将鼠标悬停在缩写上时&#xff0c;会显示一个提示框。 示例&#x…...

uniapp 字符包含的相关方法

在uniapp中&#xff0c;如果你想检查一个字符串是否包含另一个子字符串&#xff0c;你可以使用JavaScript中的includes()方法或者indexOf()方法。这两种方法都可以达到目的&#xff0c;但它们在处理方式和返回值上有所不同。 使用includes()方法 includes()方法用于判断一个字…...

作为测试我们应该关注redis哪些方面

1、功能测试 数据结构操作&#xff1a;验证字符串、列表、哈希、集合和有序的基本操作是否正确 持久化&#xff1a;测试aof和aof持久化机制&#xff0c;确保数据在开启后正确恢复。 事务&#xff1a;检查事务的原子性和回滚机制。 发布订阅&#xff1a;确保消息正确传递。 2、性…...

如何配置一个sql server使得其它用户可以通过excel odbc获取数据

要让其他用户通过 Excel 使用 ODBC 连接到 SQL Server 获取数据&#xff0c;你需要完成以下配置步骤&#xff1a; ✅ 一、在 SQL Server 端配置&#xff08;服务器设置&#xff09; 1. 启用 TCP/IP 协议 打开 “SQL Server 配置管理器”。导航到&#xff1a;SQL Server 网络配…...

jdbc查询mysql数据库时,出现id顺序错误的情况

我在repository中的查询语句如下所示&#xff0c;即传入一个List<intager>的数据&#xff0c;返回这些id的问题列表。但是由于数据库查询时ID列表的顺序与预期不一致&#xff0c;会导致返回的id是从小到大排列的&#xff0c;但我不希望这样。 Query("SELECT NEW com…...

TCP/IP 网络编程 | 服务端 客户端的封装

设计模式 文章目录 设计模式一、socket.h 接口&#xff08;interface&#xff09;二、socket.cpp 实现&#xff08;implementation&#xff09;三、server.cpp 使用封装&#xff08;main 函数&#xff09;四、client.cpp 使用封装&#xff08;main 函数&#xff09;五、退出方法…...