您的位置: 游戏资讯 > 游戏问答

java性能优化,我的世界性能优化模组

来源:[db:H1] 浏览:0 2024-05-23 05:48:05

优化功耗是优化应用体验的一个重要课题。高功耗让用户担心续航,导致加热体验不佳,降低了用户使用产品的积极性。此外,功耗是一个全面而复杂的指标,涉及整个机器在一段时间内、多种场景下的情况,影响因素很多。定量功耗分析、异常问题监控和主动功耗优化对于开发人员来说是具有挑战性的任务。本文结合抖音的功耗优化实践,得出实验结论和优化思路。了解Android应用的功耗优化,从功耗、功耗配置、功耗分析、功耗优化等基础知识入手。概括。

java性能优化,我的世界性能优化模组

功耗基础知识介绍首先我们回顾一下功耗的概念,功耗常常与能源消耗混淆。解释为什么手机用mA(电流值)来表示功耗水平,用mAh(物理充电值)来表示能耗水平。我们首先看一些物理公式。 P=IU,E=PT 能量消耗(E):能量损失。指计算机系统在给定时间内的总能耗。单位为焦耳(J)。功耗(P):指功率损耗,单位。一段时间内的能源消耗量反映了能源消耗率。单位为瓦(W)。电流(I):指手机电池放电的电流值。 mA 常用于手机。单位电压(U):指手机电池放电时的电压值,标准放电电压为3.7V,充电终止电压为4.35V,放电终止电压为2.75V(取标准值)可能会有所不同,例如,设备的电池电压值不同)电池容量:常见单位mAh,从单位意义上讲,是充电次数,真正表达的是电池持续时间需要时间在正常电压下放电。如下功耗测试图所示,手机通常工作在恒定的代表电压下,但为了计算方便,假设电压恒定为3.7V,P=I3.7,E=I3.7T它成为了。以mA功耗来表征,mAh代表能量消耗。概述:对于同一型号,用电池容量(mAh)的变化来表征一段时间内的总能耗,用平均电流(mA)来表征功耗水平(例如手机)。配备4000mAh电池时,使用TikTok 1小时将消耗11%电量,功耗(能耗)440mAh,平均电流440mA

图1. 功耗测试图

为什么需要功耗优化呢?综上所述,我们发现高功耗会导致用户对续航的担忧,同时也会导致加热体验不佳,降低用户的使用积极性。除了优化功耗来改善用户体验、增加用户屏幕使用时间之外,用最新的流行语来说,降低应用程序的功耗具有明显的社会价值,还可以为推动碳中和做出贡献。

如何优化功耗在分析时很容易混淆,因为与崩溃、ANR 等常见APM 指标不同,功耗是一个首要主题。用户反映的功耗问题可能是由于CPU负载过高、后台频繁网络访问或动画泄漏导致的高功耗引起的。或者说,我们自己的业务没有改变,只是环境因素的影响导致用户感知电量消耗,比如锂电池因低温导致的放电衰减。我们的想法是从设备入手。应用功耗最终可以分解为手机设备功耗。那么,首先我们来细分一下抖音设备的功耗,看看哪些设备主要耗电。您可以考虑降低功耗和目标设备使用率的方法。接下来我们将从功耗配置、功耗分析、功耗优化三个角度来讲解如何优化功耗。

这里的功耗配置是手机硬件基本形态的罗列,各个模块都是由复杂的器件组成。例如,高耗电的SoC通常被认为在CPU、GPU、DDRC(内存接口)中包含非常大的核心、大核心、小核心,以及外围区域的各种小型IP核心。因此,最终可以将整机的功耗分解为各个设备的功耗,通过计算所使用的设备产生的功耗来计算应用程序的功耗。以抖音直播场景为例,我们在固定亮度120nits、音量7格、WiFi网络的情况下,对抖音进行了设备级功耗分解。我们可以看到,抖音推送的功耗主要集中在四个模块:SOC(CPU、GPU、DDR)、显示、音频、WIFI。

计算设备功耗那么这些设备的功耗是如何分解的呢?原理是先分解设备功耗系数,建立设备功耗模型,然后计算设备功耗,目的是得到功耗计算值公式。您可以通过计算运行时的设备使用数据并将其插入功耗模型来计算设备的功耗。根据应用使用的比较,从设备的总功耗中分配应用的功耗,得到应用的设备功耗。影响设备功耗的功耗因素有很多,因此复杂性在于如何对功耗因素进行分解和建模。准确建模完成后,制造商下一步就是调整校准参数。

Google 提供了一套通用的设备功耗模型和配置解决方案,允许原始设备制造商(OEM) 根据通用解决方案调整和配置其产品的参数。 AOSP中的功耗设置以Wifi功率计算为例,如下图所示。 https://source.android.com/devices/tech/power/values

Google提供的建模方案根据不同的WIFI状态来计算功耗,WIFI状态之间的功耗差异非常明显。包括wifi.on(对应Wi-Fi开启时的基础电流)、wifi.active(对应Wi-Fi传输数据时的基础电流)、wifi.scan(单次Wi-Fi扫描基础功耗) 。 )和Wi-Fi数据传输功耗(controller.rx、controller.tx、controller.idle)。根据Wi-Fi 发送和接收数据的方式计算Wi-Fi 功耗。通过计算这些状态的持续时间或数量,并乘以相应的电流,就可以得到Wi-Fi设备的功耗。由于Google 基于通用性设计设备功耗模型,因此设备功耗水平通常只能粗略计算,并且对于特定产品,误差幅度可能很大。每个OEM通常都有基于自己硬件的功耗统计解决方案,这使得他们能够更准确地计算功耗。我们还将在这里使用Wi-Fi 作为示例。例如,OEM厂商可以根据2.4G和5G WIFI分别建模,引入天线信号变化对应的基线电流变化,统计其频点。 Wi-Fi 芯片工作并改进了频点等模型。 OEM 可以设计更准确的功耗模型,更适合其设备,并计算更准确的Wi-Fi 功耗。这是根据具体产品的硬件方案来确定的。

功耗分析从上面对功耗组件的介绍可以看出,影响功耗的因素有很多。在分析应用程序的功耗时,不仅需要一种方法来准确评估应用程序的功耗水平,还需要一种方法来分解功耗组件并找到优化点。下面分为两部分:用电评估和用电属性分析。

评估功耗正如上一篇功耗基础知识文章中提到的,使用当前值来评估应用程序的功耗水平。在离线场景下,您可以控制测试条件(固定测试模型版本、干净的背景、固定亮度、音量、稳定的网络信号条件等),测量可靠、准确的电流值并评估设备的功耗的应用程序。在线场景下,当应用退出后台(指用户运行的各种前台应用)时,用户使用场景复杂,因此在线版本监控只能获取当前前端的整机,其他采集监控后台CPU 使用率和后台功耗等指标。这里介绍一些常用的功耗评估方法。

PowerMonitor是目前业界最流行的评估机器整体功耗的方法,通过将外部电量计连接到PowerMonitor,以高频和高精度收集和评估电流。你常常想准确地看到功耗是多少,尤其是后台空闲、屏幕关闭时的电流输出以及厂商的接入测试。 Mosoon公司常用的PowerMonitorAAA10F,电流范围为1uA至6A,电流精度为50uA,采样周期为200us(5KHZ)。

然而,电池电量计PowerMonitor 的测量是最准确的。但拆解起来却很麻烦。您还可以通过Google BatteryManager提供的接口直接读取电池电量计统计信息并获取当前值。电池电量计用于估计电池容量。其基本功能是监测电压、充电/放电电流、电池温度,并估计电池充电状态(SOC)和电池完全充电容量(FCC)。典型的电量表包括电压电量表和电流电量表,电流电量表是目前手机中使用的主流电量表。

电压式电量计:简单来说就是检测当前电压,并参照电压与电池容量对应表计算出预估电量值。 电流电量计:也叫库仑计,原理是将检测电阻接在电池充电和放电路径。 ADC 测量检测电阻两端的电压,并将其转换为电池充电或放电期间的电流值。实时计数器(RTC) 将电流值与时间相结合,计算出流过的库仑量。 Android提供了BMS接口,通过属性提供电池电量计统计数据。

BATTERY_PROPERTY_CHARGE_COUNTER 剩余电池容量(以微安小时为单位) BATTERY_PROPERTY_CURRENT_NOW 瞬时电池电流(以微安为单位) BATTERY_PROPERTY_CURRENT_AVERAGE 平均电池电流(以微安为单位) BATTERY_PROPERTY_CAPACITY 剩余电池容量(以整数百分比表示) BATTERY_PROPERTY_ENERGY_COUNTER 剩余能量水平(以纳秒为单位) watts) ) tt 时间导入和roid .os .BatteryManager;导入android. content.Context;BatteryManager mBatteryManager=(BatteryManager)Context.getSystemService(Context.BATTERY_SERVICE);长电量=mBatteryManager.getLongProperty(BatteryManager.BATTERY_PROPERTY_ENERGY_COUNTER);Slog.i(TAG, '剩余电量=' + 能量+ 'nWh');以下面的Nexus9为例,该型号采用MAX17050电流电量表,分辨率为156.25uA,更新周期为175.8ms。

从实际结果来看,每款手机使用的电量计不同,因此可以直接读取的当前值的单位也不同,需要进行数据转换。为了简化电池数据采集,我们开发了Thor SDK,仅维护电流、电压、功率等指标的采集流程,并对每个模型的数据进行归一化处理。您必须仅提供需要抽样的数据。根据数据类型和采样周期,可以定期返回所需的功耗相关数据。我们对比了Thor和PowerMonitor的数据完整性,误差为5mA,满足了我们的在线监控需求。我们还确认了雷神系列功能本身对功耗的影响。可以看到,每秒采集一次,平均电流增加了0.59mA。因此,该解决方案的功耗影响非常低且合理。在线收集当前值。

制造商特定的功耗排名您还可以使用制造商提供的功耗排名来检查应用程序在一段时间内的功耗。如下华为功耗排行榜所示,将硬件和软件功耗分开,展示了具体应用的功耗。其他厂商的OV也支持比功耗,但小米只提供功耗比,不提供比功耗。入口:设置-电池-功耗排行

功耗属性虽然功耗评估可以确定应用程序的整体功耗,但要确定特定情况下功耗高的原因,需要选择其他工具进行分析。目前能直接归属于业务代码的工具主要是CPU相关的工具。这也是当前分析问题的主要方向。未来我们还计划打造流量归因等功能。下面列出。常用的分析工具。

Battery Historian是Google官方提供的一款分析工具,需要先进行功耗测试,然后通过adb检索bugreport.zip并在web工具中打开,可以提供粗略的功耗属性。

基本上就是系统服务器中各种服务统计数据+手机状态+内核统计数据(内核唤醒)的展示。应用功耗估算取决于制造商设置的power_profile.xml。适合估算机器的整体功耗,例如当特定应用程序功耗较高时。

对于单个应用程序来说,唤醒锁、警报、GPS、作业、同步服务、后台服务执行时间等统计数据相对粒度较细,适合了解后台功耗。关于网络异常和CPU异常,我们只看到高消耗,并不归因于特定服务。 https://developer.android.com/topic/performance/power/setup-battery-historian hl=zh-cn

相比BatteryHistorian,AS Profiler首先需要手动测试,配合adb capture配合起来比较麻烦,但AS自带的Profiler可以直观地显示电量。该应用程序的调试版本可以让您直观地检查功耗,使离线测试更容易。注意,这里显示的功耗值是使用GPS+网络+CPU计算出的拟合值,并非实际功耗值,仅代表功耗水平。

Profiler同时显示CPU使用率、网络功耗和内存信息。支持CPU和线程级跟踪。通过主动记录踪迹,可以分析每个线程的CPU使用率和函数耗时。对于容易重现的高CPU负载问题或固定场景下的耗时问题,可以使用此方法轻松找出根本原因。但迹线显示方式并不适合CPU负载偶尔较高的情况,信息量大,难以掌握要点。 Network Power 可以让您轻松捕获上下游网络请求,查看网络请求的API 详细信息,并将其划分为线程。频繁访问网络可以更轻松地发现问题区域。不过,目前仅支持通过HttpURLConnection 和OkHttp 进行的网络请求,Profiler 无法跟踪使用其他网络库。

虽然官方工具功能比较丰富,但仅支持分析应用程序的调试版本,如果要分析已发布的应用程序,则需要使用root手机。 Profiler 通常更适合某些业务场景的离线分析。 https://developer.android.com/studio/profile/energy-profiler

监控线程池您可以使用上述工具来监控单线程CPU异常。然而,诸如线程池、处理程序和AsyncTasks之类的异步任务,尤其是网络库中的线程池,它们执行的网络请求具有相同的逻辑,因此不容易将它们简单地归因于特定任务。获取线程堆栈。要了解实际问题,需要统计提交任务的源码。可以使用各种机制来详细记录和聚合提交的任务,包括对线程池和Java钩子的修改。这对于分析线程池中的耗时任务很有用。

准确的在线CPU异常监控除了离线CPU分析之外,在构建在线CPU异常监控时,仅使用CPU使用率阈值并不能准确判断进程是否出现CPU异常。例如,不同的CPU型号性能不同,一些低端CPU的利用率相对较高。另一个例子是系统有不同的温度控制和节能策略,限制手机频率并迁移任务的CPU核心。在这种情况下,应用程序的CPU使用率也会很高。因此,根据各种变量(CPU型号、进程/线程在不同核心上的CPU时长分布、不同频率、充电、电量、内存、网络状态等),可以对CPU使用率阈值进行准确判断。针对不同场景、不同设备、不同业务制定完善的CPU异常阈值,从而实现高精度的CPU异常捕获。另外,业界还有一些归因框架,这里就不一一介绍了。

Facebook BatteryMetrics:从CPU/IO/位置等各种属性点收集数据。与系统BatteryStatsService的统计行为类似,专注于离线应用电量评估和设备拆解。微信BatteryCanary:提供了线程和线程池属性功能,相比其他工具增加了前后端、屏幕开关、充放电、前端服务统计等统计功能。实践功耗优化上面我们介绍了功耗的组成部分以及如何分析应用程序的功耗。本节对功耗优化进行总体介绍。我们从设备角度延伸优化思路,列出了可以减少设备使用、降低功耗的优化思路和对策。此外,对于一些用户可能认为对服务造成损害的降级,我们使用低功耗模式来减少用户对电池的担忧,减少电量不足时的电池焦虑,通过更积极的降级来增加用户的使用时间。下图展示了每个设备的优化思路。一些优化想法有利于多种设备。这里没有特别详细的区别。分为主要影响它的设备,比如刷新区域的减少。 GPU和CPU、DDR都有优势,主要优势在GPU渲染上,如下图GPU下面所列。同时我们列出了厂商方面的一些优化方案,比如降低屏幕刷新率、降低TP扫描频率、降低整机分辨率等,这些在应用中通常不需要特别注意。动态调整屏幕刷新率的场景将与厂商合作动态调整屏幕刷新率搜索列表中的场景将采用90HZ 高刷新率短视频场景将采用90HZ 高刷新率,降低刷新率90HZ,结合30HZ和帧率节流,实现更平衡的功耗和性能体验。

DISPLAY 优化显示功耗主要集中在降级或减少对屏幕、GPU、CPU、视频解码器、TP等设备的处理,尽可能使用硬件处理。我是。关于屏幕,主要会降低亮度、刷新率、TP扫描频率等。

屏幕亮度屏幕亮度是屏幕功耗的最大原因。亮度和功耗之间几乎成正比关系。参见下图:

可以看出,对于IPS 和OLED 屏幕,随着屏幕亮度的增加,功耗几乎呈线性增加。对于OLED屏幕来说,白色内容的功耗较高,但黑色内容的功耗相对较低。降低应用程序亮度的常见方式包括进入应用程序后主动降低亮度或使用Dark UI模式来达到降低屏幕亮度的效果。制造商使用FOSS 或CABC 解决方案来降低屏幕亮度。深色模式利用了AMOLED屏幕本身的原理,由于黑色功耗最低,所以可以将主题颜色设置为较暗的颜色,最终降低功耗并长时间使用。为什么AMOLED屏幕在显示黑色界面时耗电较少呢?这是由于与传统LCD屏幕的发光原理不同所致。 LCD背光显示器主要依靠背光层,其中发射层由多个LED灯泡组成,显示白光,以及液晶层的偏振控制来显示RGB颜色。在这种情况下,黑色与其他颜色的像素没有什么不同;它看起来并不明亮,但仍然发光。 AMOLED 屏幕根本没有背光。反之,每个微小的子像素只发出微弱的RGB光,当屏幕需要显示黑色时,可以调节电压来旋转液晶分子并阻挡背光,而不点亮其他颜色,这样就可以实现黑色的效果。

下面是使用测试应用Reddit Sync 在不同场景下彩色模式和黑色模式的功耗对比。 (参考链接:https://m.zol.com.cn/article/4895723.html#p4)

从上图可以清楚地看到,在黑色背景下,AMOLED 屏幕比在普通彩色背景下消耗的能量要少得多。在Reddit Sync测试中,平均功耗降低了40%。该应用程序可以设计您自己的深色模式主题并同步您手机系统的深色模式切换开关。目前,抖音的背景设置有两种模式:经典模式是深色模式,对应深色主题,可以与移动平台上的深色模式结合使用。

FOSSFOSS(保真优化信号缩放)是芯片制造商提供的用于AMOLED 屏幕调节的低功耗解决方案。 LCD 屏幕上的对应项是CABC(内容自适应亮度控制)。一方面降低了屏幕亮度,另一方面调整了显示内容的灰度值,因此显示效果没有太大差异,但由于屏幕亮度降低,功耗增益较大。减少。一般为0.2小时左右,所以这意味着你的手机平均使用时间可以延长0.2小时左右。众所周知,制造商的FOSS 解决方案在某些参数下的个别场景中可能会出现变色和闪烁问题。如果您遇到不明闪烁问题,且无法通过内部定位确定原因,可以咨询厂家解决问题。

降低刷新率:现在市面上有些手机支持60HZ、90HZ、120HZ、144HZ等。较高的刷新率可以提高流畅度并改善用户体验,但也会消耗更多电量。通常情况下,桌面、设置等系统应用界面会根据当前系统设置匹配刷新率,但具体应用会根据不同场景调整刷新率。以抖音为例,即使是高刷新屏幕,功耗也相对较低,因为平台系统通常选择以60HZ刷新率运行抖音。 PhoneArena 创建了相关参考数据来验证不同刷新率的这一观点。我们选取了两个品牌的四款高刷新率机型,在相同条件下分别以60Hz和120Hz刷新率进行测试,发现120Hz刷新率确实会缩短手机的续航时间。相比60HZ刷新率至少慢了10秒.%,即使支持90Hz的一加8也比60HZ刷新率差。

图片来源:https://www.sohu.com/a/394532665_115511

降低TP 扫描频率。游戏通常会使用较高的TP扫描频率来提高点击响应速度,而其他场景则使用默认扫描频率。抖音一般使用默认的TP扫描帧率。

GPU GPU优化的思路主要是减少不必要的绘制或者减少绘制区域,体现在较低的分辨率、较低的帧率、较少的绘制层数等。此外,使用SurfaceView 而不是TextureView 的视频应用程序也将实现显着的节能。对于复杂的运算,可以选择节能的设备来运行,例如使用硬件渲染代替软件渲染,或者使用NPU代替GPU来运行复杂的算法,这样可以显着降低整体功耗。

低分辨率应用程序低分辨率此模式通常以较低的分辨率运行游戏和某些应用程序。 GPU绘图区和传输区的大小有所减小,从而降低了GPU和CPU的功耗以及DDR传输。游戏场景下功耗优势较大,在部分平台离线测试中1080p转720p约20mA,1440p转720p约40mA。原理是应用层以低分辨率绘制,通过HWC通道放大到屏幕分辨率,与其他层结合显示。

示时浪费不必要的资源去渲染看不见的背景,或者对某些像素区域多次绘制,就会导致界面加载或者滑动时的不流畅、掉帧,对于用户体验来说就是 App 特别的卡顿。为了提升用户体验,提升应用的流畅性,优化过度绘制的工作还是很有必要做的。抖音的 feed 页的过度绘制非常的严重,抖音存在 5 层过度绘制。下图左侧是优化前的过渡绘制情况,右侧是优化后的过度绘制情况,可以看出优化后明显改善。 使用 SurfaceView 视频播放TextureView 和 SurfaceView 是两个最常用的播放视频控件。TextureView 控件位于主图层上,解码器将视频帧传递到 TextureView 对象还需要 GPU 做一次绘制才能在屏幕上显示,所以其功耗更高,消耗内存更大,CPU 占用率也更高。控件位置差异如下,可以看出 SurfaceView 拥有独立的 Surface 位于单独的图层上,而 TextureView 位于主图层上。 BufferQueue 是 Android 图形架构的核心,其一侧是生产者,另一侧是消费者。从这方面看,SurfaceView 和 TextureView 的差异如下。容易看出,SurfaceView 流程更短,内存使用更少,也没有 GPU 绘制,功耗更省。 下面是一些 SurfaceView 替换 TextureView 后的收益数据: CPU 数据上看,SurfaceView 要比 TextureView 优化 8%-13%功耗数据上看,SurfaceView 要比 TextureView 平均功耗低 20mA 左右。硬件绘制和软件绘制硬件绘制是指通过 GPU 绘制,Android 从 3.0 开始支持硬件加速绘制,它在 UI 显示和绘制效率方面远高于软件绘制,但是 GPU 功耗相对较高。目前是系统默认的绘制方式。软件绘制是指通过 CPU 实现绘制,Android 上面使用 Skia 图形库来进行绘制。两者差异参见下图。 目前默认是开硬件加速的,可以通过设置 Activity,Application,窗口,View 等方式来指定软件绘制。如果应用需要单独指定某些场景的软件绘制方式,需要对性能、功耗等做好评估。参考链接:https://developer.android.com/guide/topics/graphics/hardware-accel 复杂算法用 NPU 代替 GPU现在的较新的 SoC 平台都带有专门进行 AI 运算的 NPU 芯片,使用 NPU 代替 GPU 运行一些复杂算法,可以有效的节省 GPU 功耗。如视频的超分算法,可以给用户带来很好的体验。但是超分开启对 GPU 的耗电影响很大,在某些平台测试整机功耗可以高出 100mA,选择用 NPU 替换 GPU 是一种优化方式。 CPUCPU 的优化是功耗优化里最常见的,我们遇到的大部分的 CPU 异常都是出现了死循环。这里使用上面介绍过的功耗归因工具,都可以很容易的发现死循环问题。此外高频的耗时函数,效果和死循环类似,很容易让 CPU 大核跑到高频点,带来 CPU 功耗增加。另外一个典型的 CPU 问题,就是动画泄漏,泄漏动画大概能带来 20mA 的功耗增加。由于 CPU 工作耗电很高,手机平台大多会增加各种低功耗的 DSP 来分担 CPU 的工作,减少耗电,如常见视频解码,使用硬解会有更好的功耗表现。 CPU 高负载优化死循环治理死循环是我们遇到的最明显的 CPU 异常,通常表现为某一个线程占满了一个大核。线程使用率达到了 100%,手机会很容易发热,卡顿。这里举一个实际修复的死循环例子,在一段循环打包日志的代码逻辑里,所有 log打包完了,才会break跳出循环。当db query出现了异常,异常处理分支并没有做break,导致出现了死循环。 // 方法逻辑有裁剪,仅贴出主要逻辑private JSONArray packMiscLog() { do { ...... try { cursor = mDb.query(......); int n = cursor.getCount(); ...... if (start_id >= max_id) { break; } } catch (Exception e) { } finally { safeCloseCursor(cursor); } } while (true); return ret;}对于死循环治理,我们通过实际解决的问题,总结了几种常见的死循环套路。 // 边界条件未满足,无法breakwhile (true) { ... if (shouldExit()) { break }}// 异常处理不妥当,导致死循环while (true) { try {do someting;break; } catch (e) { }}// 消息处理不当,导致Handler线程死循环void handleMessage(Message msg) { //do something handler.sendEmptyMessage(MSG)}高频耗时函数治理除了死循环问题,我们遇到的另外一种常见的就是高频的耗时函数。通过线上监控 CPU 异常,我们也找到很多可优化的点。如 md5 压缩算法的耗时,正则表达式的不合理使用,使用 cmd 执行系统命令的耗时等。这种就 case by case 的修复,就有很不错的收益。 后台资源规范使用Alarm,Wakelock,JobScheduler 的规范使用最常见的后台 CPU 耗电就是对后台资源的不合理使用。Alarm 的频繁唤醒,wakelock 的长时间不释放,JobScheduler 的频繁执行,都会使 CPU 保持唤醒状态,造成后台耗电。这种行为很容易让系统判断应用为后台异常耗电,通常会被系统清理,或者发出高耗电提醒。我们可以通过 dumpsys alarm & dumpsys power & dumpsys jobscheduler 查看相关的统计信息,也可以通过 BH 的后台统计来分析自身的使用情况。参考绿盟的功耗标准,灭屏 Alarm 触发小于过 12 次/h,即 5min 一次,5min 一次在数据业务下可以保证长链接存活,厂商的后台功耗优化也通常会强制对齐 Alarm 为 5min 触发一次。后台的 Partial Wakelock 通常会被重点限制,非可感知的场景(音乐,导航,运动)等会被厂商强制释放 wakelock。按照绿盟的标准,灭屏下每小时累计持锁小于 5min,从实际经验上看,持 Partial 锁超过 1min 就会被标为 Long 的 wakelock,如果是应用在后台无可感知业务并且频繁持锁,导致系统无法休眠的,系统会触发 forcestop 清理。 某些定时任务可以使用 JobScheduler 来替代 Alarm,Job 的好处是可以组合多种触发条件,选择一个最恰当的时刻让系统调度自己的后台任务。这里建议使用充电+网络可用状态下处理自己的后台任务,对功耗体验是最好的。如果是非充电场景下,设置条件频繁触发 job,同样会带来耗电问题。值得一提的是 Job 执行完要及时结束。因为 JobScheduler 在执行时会持有一个*job/*开头的 wakelock,最长执行时间 10min,如果一直在执行状态不结束,就会导致系统无法休眠。 视频硬解替换软解硬解通常是用手机平台自带的硬件解码器来做解码从而实现视频播放,基于专用芯片的硬解码速度快、功耗低;软解码方面,通常使用 FFMPEG 内置的 H.264 和 H.265 的软件解码库来做解码。下表是三星手机和苹果手机分别在软硬解情况下的功耗,可以看出硬解功耗比软解功耗显著降低,目前抖音默认使用硬解。 图片来源:http://www.noobyard.com/article/p-eedllxrr-qz.html NETWORK网络耗电是应用耗电的一个重要部分,一个数据包的收发,会同步拉动 CPU 和 Modem/WIFI 两大系统。由于 LTE 的 CDRX 特性(即没有数据包接收,维持一定时间的激活态,再进入睡眠,依赖运营商配置,通常为 10s),所以批量进行网络访问,减少频繁的网络唤醒对网络功耗很有帮忙。此外优化压缩算法,减少数据传输量也从基础上减少了网络耗电。此外弱信号条件下的网络请求会提高天线的功率,也会触发频繁的搜网,带来更高的网络功耗。根据网络质量进行网络请求调度,提前预缓存网络资源,可以减少网络耗电。 长链接心跳优化对于应用的后台 PUSH 来说,使用厂商稳定的 push 链路替代自己的长链接可以减少功耗。如果不能替换,也可以优化长链接保活的心跳,根据不同的网络条件动态的调整心跳。根据经验,数据业务下通常是 5min,WIFI 网络下通常可以达到 20min 或更久。抖音对于长链接进行了的心跳优化,进入后台的长链接心跳时间间隔 [4min, 28min],初始心跳 4min。采用动态心跳试探策略,每次步进 2min,确定最大心跳间隔。 Doze 模式适配由于系统对后台应用有多种网络限制策略,最常见的是 Doze 模式,手机灭屏一段时间后会进入 doze,限制非白名单应用访问网络,并在窗口期解除限制,窗口期为每 10min 放开 30s。所以在后台进行网络访问前要特别注意进行网络可用的判断,选择窗口期进行网络访问,避免因为被限网而浪费了 CPU 资源。这里举一个 Doze 未适配的后台耗电例子,用户反馈抖音自上次手机充满电(24h)后,没有在前台使用过,耗电占比 31%,分析日志发现 I 在 Doze 限制网络期间,会触发轮询判断网络是否及时恢复,此逻辑在后台未适配 Doze 的窗口期模式,导致了后台频繁尝试网络请求带来的 CPU 耗电。 AUDIO降低音量音频的耗电最终体现在 Codec 和 SmartPA(连接喇叭的功率放大器)两部分。减少 Audio 耗电最明显的就是减少音频的音量,这直接反应到喇叭的响度上。用 0-15 级的音量进行测试,可以看到音量对功耗的影响巨大,尤其是超过 10 之后,整体增幅非常巨大。每一级几乎与功耗成百分比上涨。 10-15 :1:30ma5-10:1:1.62ma0-5:1:1.36ma调整音频参数由于用户对音量的感受很明显,直接全局降低音量会带来不好的体验。厂商通常会针对不同的场景,设计不同的音频参数,如电影场景,游戏场景,导航场景,动态调节音频的高低频配置参数,兼顾了效果和功耗。从这个角度出发,可以选择和厂商合作,根据播放视频的内容,精细化调整音频参数,如电影剪辑类型视频就使用电影场景的参数,游戏视频就切换为游戏场景的配置参数,从而达到用户无感调节音量节省功耗的目的。 CAMERACamera 是功耗大户,尤其是高分辨率高帧率的录制会带来快速的功耗消耗和温升。经过线下测算,开播场景,Camera 功耗 200mA+,占整机的 25%以上。 优化Camera功耗的思路主要是从业务降级的角度上进行,如降低录制的分辨率,降低录制帧率等。之前抖音直播和生产端都是使用30帧,但最终只使用15帧,在开播端主动下调采集帧率,按需设置帧率为15帧,功耗显著降低了120ma。 SENSORsensor 的典型功耗值很低,如我们常用到的 accelerometer(加速度计)的典型功耗只有 180uA。但 sensor 的开启会导致 cpu 的唤醒与负载增加,尤其是在应用退到后台,sensor 的滥用会显著增加待机功耗。可以在低电量时关闭不必要的 sensor,减少耗电。 GPS精确度,频率,间隔是影响 GPS 耗电的三个主要因素。其中精度影响定位的工作模式,频率和间隔是影响工作时长,我们可以通过优化这三者来减少 GPS 的耗电 降低精度Android 原生定位提供 GPS 定位和网络定位两种模式。GPS 定位支持离线定位,依靠卫星,没有网络也能定位,精度高,但功耗大,因需要开启移动设备中的 GPS 定位模块,会消耗较多电量。Network 定位(网络定位),定位速度快,只要具备网络或者基站要求,在任何地方都可实现瞬间定位,室内同样满足;功耗小,耗电量小;但定位精度差,容易受干扰,在基站或者 WiFi 数量少、信号弱的地方定位质量较差,或者无法定位;必须连接网络才能实现定位。我们可以在满足定位要求的情况下,主动使用低精度的网络定位,减少定位耗电,抖音在进入低功耗模式时,进行了 GPS 降级为网络定位,并且扩大了定位间隔。 降低频率&提高间隔这里除了业务上主动控制频率与间隔外,还推荐使用厂商的定位服务。为了优化定位耗电,海外 gms 以及国内厂商都提供了位置服务 SDK,本质上是通过系统服务统一管理位置请求,根据电量,信号,请求方的延迟精度要求,进行动态调整,达到功耗与定位需求的平衡。提供了诸如被动位置更新,获取最近一次定位的位置信息,批量后台位置请求等低功耗定位能力。https://developer.android.com/guide/topics/location/battery https://developer.huawei.com/consumer/cn/doc/development/HMSCore-References/location-description-0000001088559417 低功耗模式上述的优化措施,有些在常规模式下已经实施。但有一部分是有损用户体验的,我们选择在低电量场景下去做,降低功耗,减少用户的电量焦虑,获得用户在低电量下更多使用时长。在低功耗模式预研中,我们列举了很多可做的措施,通过 AB 实验,我们去掉了业务负向的降级手段,比如亮度降低,音量降低等。此外在功能触发的策略上,我们通过对比了低电量弹窗提醒,设置里增加开关+Toast 提醒,以及低电量自动进入,最终选择了对用户体验最好的 30%电量无打扰自动进入的触发方式。 经过实验发现,一些高发热机型,通过低功耗模式全程开启,也可以拿到业务收益。说明部分有损的降级,用户在易发热的情况下也是接受的,可以置换出业务收益,目前低功耗模式线下测试功耗收益稳定在 20mA 以上。 总结功耗优化是一个复杂的综合课题,既包含了利用工具对功耗做拆解评估,对异常的监控治理,也包含了主动挖掘优化点进行优化。上面列举的优化思路,我们也只是做了部分,还有部分待开展,包括功耗归因的工具建设上,我们也还有很多可以优化的点。我们会持续发力,产出更多的方案,在满足使用需求的前提下,消耗更少的物理资源,给抖音用户带来更好的功耗体验。 加入我们 抖音 Android 基础技术团队是一个深度追求极致的团队,我们专注于性能、架构、包大小、稳定性、基础库、编译构建等方向的深耕,保障超大规模团队的研发效率和数亿用户的使用体验。目前北京、上海、杭州、深圳都有大量人才需要,欢迎有志之士与我们共同建设亿级用户的 APP! 感兴趣的同学可以点击“阅读原文”,进入字节跳动招聘官网查询「抖音基础技术 Android」相关职位,也可以邮件联系:gaoyuan.mmm@bytedance.com 咨询相关信息或者直接发送简历内推!