一、背景

今天来总结一下,自己在项目中遇到的一个CPU占用过高的问题,详细的结束从发现到定位在到解决问题的过程。

原因是性能测试那边提出了一个bug,就是在投屏过程中,平板端也就是Sink端功耗非常高的问题,

二、排查问题

经过排查后发现:需要手机投平板后在手机侧拖动平板断开,平板端的一个进程CPU占用率会一直上升,且每次重复此操作后CPU占用率都会上升,高概率复现

可以输入 adb shell top -m 10 确定排名前10的进程

三、使用android Profile工具分析

接下来可以使用Android Studio打开android Profile工具,通过选中自己应用的进程,然后点击CPU可以查看CPU的使用情况。

我们通过复现在Source端断开,可以看到Sink端的cpu使用情况:在断开后,按理说是没有线程在跑的,但是从下图可以看到其中有个线程StreamSinker_Ou一直在使用CPU,那么就可以确认是此线程出问题了。

四、使用simpleperf工具

4.1 simpleperf工具介绍

通过上面步骤后,我们可以使用simpleperf工具进行进一步分析:

simpleperf工具是在NDK的根目录下



当然Android设备都会有此工具,因此可以直接使用

4.2 simpleperf工具使用

4.2.1 抓取进程数据

simpleperf record -p 30382 --call-graph fp -o data/perf.data

执行完上面命令后,就会在data目录下生成perf.data文件

4.2.2 解析进程数据

simpleperf report -g -i data/perf.data > data/perf.log

执行完上面命令后,就可以将生成的perf.data文件解析出perf.log文件,此文件方便我们来判断具体是哪里占用CPU过高.

4.2.3 查看perf.log文件

打开perf.log文件我们可以看到占用CPU的具体的地方:是底层的android::StreamSinker::SinkerOutThread::threadLoop()方法

五、代码分析

通过上面分析后可以知道是底层的StreamSinker类的SinkerOutThread内部类的threadLoop()方法导致CPU占用过高。

此方法是一个wile循环使用一个bool变量进行控制,也就是说在断开后,此bool值没有置为false,控制此bool值为false也就是上图的stop方法里。

通过代码的定位最终定位到了MultiscreenSink类的doMessageReceived方法的kWhatStop条件中

而触发此kWhatStop条件是在MultiscreenSink类的stop方法中

status_t MultiscreenSink::stop(void) {
LOGD(NEGOTIATE_DEBUG,"stop prepare send kWhatStop messg");
sp<AMessage> msg = new AMessage(kWhatStop, mWorkHandler);
msg->post();
return OK;
}

我们在通过复现时的日志可以发现:刚调用stop方法,就开始走了MultiscreenSink类的析构方法,导致stop方法里AMessage还未及时发送出去

六、问题解决

通过上面代码分析后,知道了具体的问题在哪里,那么接下来就可以更好的解决问题了,具体解决方法这里就不在描述了,只要知道具体问题点了,那么就会有很多方案去处理。

之后解决的效果如下,基本上投屏中CPU占用始终在70%左右,退出投屏此进程也就不在top 10中了。

参考:

解决CPU使用过高问题

投屏项目中Sink端CPU占用过高问题的更多相关文章

  1. 项目中Map端内存占用的分析

      最近在项目中开展重构活动,对Map端内存尽量要省一些,当前的系统中Map端内存最高占用大概3G左右(设置成2G时会导致Java Heap OOM).虽然个人觉得占用不算多,但是显然这样的结果想要试 ...

  2. 工具运行过程中,CPU占用过高的分析定位

    之前使用Java Swing开发了一款设备档案收集工具.支持多台设备同时收集,每个设备使用一个线程.在同时收集多台设备信息时,发现CPU占用率居然达到了97%,而且高居不下.显然这样的性能是令人无法忍 ...

  3. 记一次用arthas排查jvm中CPU占用过高问题

    记一次使用arthas排查jvm中CPU占用过高问题.这工具屌爆了 碾压我目前使用的全部JVM工具. 安装 小试 curl -O https://arthas.aliyun.com/arthas-bo ...

  4. 一次java Cpu占用过高的排查

    某一个项目CPU占用率一直很高,经常在40%-50%之间,最近比较闲,就开始了排查工作. 1.通过 jstack命令输出进程的堆栈信息 jstack 2788 >C:\log.txt 将堆栈信息 ...

  5. 【笔记】排查CPU占用过高

    本文是该教程视频的笔记 https://www.bilibili.com/video/BV15T4y1y7eH 1. 问题演示 将演示项目打包放到服务器运行 执行 curl http://localh ...

  6. Android去除CPU占用过高时屏幕四周闪红框

    话说有些时间没有更新博客了,今天正好解决这个问题,顺便把它记录下来.. 今天遇到的情况是这样的,当CPU占用过高时,屏幕四周会出现一个红框. 闪一次两次算了,但是挺萌的(TMD)不停的闪,我的钛合金狗 ...

  7. 性能测试问题_Mysql数据库服务器的CPU占用很高

    MySQl服务器CPU占用很高 1.  问题描述 一个简单的接口,根据传入的号段查询号码归属地,运行性能测试脚本,20个并发mysql的CPU就很高,监控发现只有一个select语句,且表建立了索引 ...

  8. java 一次CPU占用过高问题的排查及解决

    最近一段时间  某台服务器上的一个应用总是隔一段时间就自己挂掉      用top看了看  从重新部署应用开始没有多长时间CPU占用上升得很快 排查步骤 1.使用top 定位到占用CPU高的进程PID ...

  9. kswapd0 进程CPU占用过高

    前几天遇到的一个问题,自己本地用VM配置的虚拟机,一般会top查看进程以及CPU占用的一些情况.又一次用laravel 打印对象,里面的内容比较多,浏览器当时就卡了. 然后看进程的情况.我以为会是ng ...

  10. 一次单核CPU占用过高问题的处理

    客户现场反馈,top的检查结果中,一个CPU的占用一直是100%.实际上现场有4个CPU,而且这个服务器是mysql专属服务器. 我的第一反应是io_thread一类的参数设置有问题,检查以后发现re ...

随机推荐

  1. uni-uadmin后台管理系统|uniapp+uView跨端后台框架实例

    基于uniapp+uview+uni-ui跨平台手机端后台管理系统UniappUAdmin. uniapp-uadmin 基于uni-app+uView+uniUI研发的跨端手机后台管理系统项目.全新 ...

  2. Exadata健康检查工具EXAchk

    本文根据MOS文章:Oracle Exadata Database Machine EXAchk (Doc ID 1070954.1)整理关键步骤. 注:通常都会要求使用当前最新可用的EXAchk版本 ...

  3. JS Leetcode 304. 二维区域和检索 - 矩阵不可变,彻底弄懂二维数组前缀和

    壹 ❀ 引 我在JS LeetCode 303. 区域和检索 - 数组不可变,一维数组的前缀和一文中,记录了一维数组求区间合的解题思路,正好还有一题的升级版,题目来自leetcode304. 二维区域 ...

  4. SpringBoot相关注解使用

    @MapperScan注解和@Mapper @Mapper常用在相应的 *Mapper类上,但是每个类都使用相对麻烦,所以后来用@MapperScan替代 ,@MapperScan注解使用在启动类上. ...

  5. ORA-31655,ORA-39154 Objects from foreign schemas have been removed from import

    问题说明 在执行数据泵导入时提示错误: 问题原因 执行导入的用户缺少导入数据库的权限. 解决问题 给用户赋予导入数据库权限: grant imp_full_database to 用户; 然后重新执行 ...

  6. CSS实现页脚始终在页面底部

    说明 最近在布局自己的博客系统,我是想练练手把时下比较流行的前后端技术串起来.同时,我会把设计和编码过程中遇到的问题或值得分享的技术点.实现方式做下总结,记录下来.本篇就是第一篇,个人能力有限,不足之 ...

  7. Vmware中Linux通过NAT设置静态IP实现上网

    1.设置虚拟机上网方式为NAT 2.修改centos网络配置文件,我的是centos7.4,主要网关不能和主机设置的一致 [root@dylan-centos ~]# vi /etc/sysconfi ...

  8. 《系列二》-- 9、bean属性填充

    目录 一.概述: populateBean 在什么时候执行? 二.populateBean 的重要操作 三.重点操作一 propertyValue 的注入 3.1 根据 Bean名称注入 3.2 浅看 ...

  9. win32 - 创建子线程中的窗口

    跟创建普通的win32窗口一样,线程中的窗口也需要注册和窗口处理过程 // Test_WM_CLOSE.cpp : Defines the entry point for the applicatio ...

  10. 【LeetCode栈与队列#04】逆波兰表达式求值(仍然是经典的栈操作)

    逆波兰表达式求值 力扣题目链接(opens new window) 根据 逆波兰表示法,求表达式的值. 有效的运算符包括 + , - , * , / .每个运算对象可以是整数,也可以是另一个逆波兰表达 ...