你的浏览器无法流畅使用爱设计。要想获得最佳体验,可以升级到最新版的 谷歌 Chrome 浏览器 下载安装 >>

APP性能设计及优化专题——影响性能的不良实现

2022-08-11

继介绍性能设计概述性能优化建议后,本文将重点介绍影响性能的不良实现,主要包含Binder共享内存耗尽、Binder线程池耗尽、创建大量BpBinder或Binder对象等方面。

为了更好地了解下文内容,我们先简单介绍一下Binder:

【注】由于Binder机制的复杂性,这里不展开介绍,仅简单概括,便于更好理解本文内容。

Binder属于一种IPC通信机制,是用来实现不同进程间通信的,主要由ServiceManager、Server(服务端)、Binder 驱动、Client(客户端)4 部分构成,其中Client、Server、Service Manager运行在用户空间,Binder驱动运行在内核空间。一次完整的 Binder IPC 通信过程通常如下:

1)Binder 驱动在内核空间创建一个数据接收缓存区;

2)在内核空间开辟一块内核缓存区,建立内核缓存区和内核中数据接收缓存区之间的映射关系,以及内核中数据接收缓存区和接收进程用户空间地址的映射关系;

3)发送方进程通过系统调用 copy_from_user()将数据 copy 到内核中的内核缓存区,由于内核缓存区和接收进程的用户空间存在内存映射,因此也就相当于把数据发送到了接收进程的用户空间,完成一次进程间的通信。

由于Binder在跨进程通信过程中担任着极其重要的作用,任何流程或异常都会带来负面影响。


01

Binder共享内存耗尽

Binder的性能(减少一次copy_to_user)和安全是最大优势,但由于Binder在内核和用户态都对传输的数据量有限制,因此要避免通过Binder传输大量数据。一个进程用于接收Binder数据的共享内存为1M-8K,对于oneway要减半。同时,Binder driver也有4M上限的限制,当多个线程共用这块共享内存时,一旦driver发现数据接收方共享内存不够,就会返回错误。

Binder共享内存耗尽的影响:

Binder调用耗时长,甚至失败;

若是用户操作的关键流程,则会导致卡顿发生。

优化建议:

及时释放data(Server端)或reply(Client端),建议用AIDL框架;

Binder接口设计时避免大数据的参数传递,若有需要可用Ashmem传递;

避免短时间内大量线程同时并行调用某Server,若有需要,需做削峰处理。


02

Binder线程池耗尽

Server端有一定数量的Binder线程池来响应Client的调用,一个进程的Binder线程数默认最大是16(1个主线程和15个非主线程),超过的请求会被阻塞等待空闲的Binder线程,即Binder线程池耗尽会导致后面的调用被阻塞。

Binder线程池耗尽的影响:

同步调用的Client端被阻塞,若是用户操作的关键流程中,则发生卡顿现象;

system_server等系统关键服务进程的Binder线程池耗尽,则造成整机卡顿。

优化建议:

避免短时间内大量线程同时并行调用某Server,若有需要则需做削峰处理;

提升Binder接口实现的执行效率。


03

创建大量BpBinder或Binder对象

BpBinder是客户端中的Binder引用,保存着目标服务的handle信息,即服务端的Binder实体的引用信息,用于查询内核中的Binder节点,并同Binder实体通信。

系统并未限制Server端的Binder对象创建,理论来说可以大量创建,但一个Service应该仅创建一个Binder对象,BpBinder对象有上限6000/2500个,多了会被杀掉,因此建议同一个Service的BpBinder实现进程内共用。

创建大量BpBinder或Binder对象的影响:

内存占用,频繁GC,甚至因OOM而闪退;

整机卡顿。

优化建议:

一个Service仅一个Binder对象实例,按使用场景和生命周期合并Service;

及时释放不再使用的BpBinder。


04

使用多个ServiceConnection对象Bind同一个Service

ServiceConnection其实也是一个Service,提供给AMS维护,用于管理目标Service的回调。同一个ServiceConnection对象可以管理多个Service,Client端已做到对不同Service的复用,AMS仅维护一个IServiceConnection;但不同ServiceConnection对象没有做到复用,即使是同一个Service。

使用多个ServiceConnection对象Bind同一个Service的影响:

增加AMS的维护负担,Service的启动/退出都会持有AMS锁后遍历SC;

长时间持有AMS锁,导致整机卡顿。

优化建议:

复用同一个ServiceConnection对象,特别是同一个Service;

监听Service的死亡回调,若有需要可立即重新Bind;

及时unbind不再使用的Service。


04

随用随获取系统服务

系统服务由ServiceManager维护,获取系统服务IBinder的过程也是一次跨进程Binder调用。应用常用的系统服务在应用进程启动时就已由ATMS带过去了,而其他系统服务系统对普通应用使用hiden接口来限制。当出现频繁调checkService接口的,主要是系统服务或系统应用。

随用随获取系统服务影响:

不必要的跨进程同步调用耗时1ms左右,有些甚至达到s级(logcat -b events -s service_manager_slow);

增加系统负荷。

优化建议:

一次获取成功后本地缓存;

通过IBinder的linkToDeath机制感知到服务的退出,服务退出后清除本地IBinder缓存,下次需要时再次向Servicemanager获取。

除了上述的不良实现外,还有组件对象泄漏(原生的removeContextRegistrations中有对SC、Receiver和Window泄漏的检查)、系统核心进程调用非ONEWAY的IPC接口(会带来核心进程卡死的风险)以及HIDL仅用于跨进程间调用(对于Client和Server共进程的场景,不要使用HIDL)等。

到这里,APP性能设计及优化专题告一段落,欢迎大家后台留言,发表您对文章的见解,或反馈您想查看的内容,希望我们一起进步哦~


相关阅读

APP性能设计及优化专题——性能设计概述篇

APP性能设计及优化专题——性能优化建议篇


行业活动推荐

第十届MTSC大会 · 深圳

中国互联网测试开发大会(Testing Summit China),由国内最大的测试开发技术社区之一TesterHome发起,始于 2015 年,已成功举办了九届。

从500 多人到 2000 人,从一天的议程到两天,从8个topic到60+topic,从北京到上海到深圳:MTSC 测试大会已经成功塑造了落地、务实、有深度的千人大会形象。

MTSC 2022 深圳站,第十届中国互联网测试开发大会:共有1个主会场和12大专场专场包括:知乎、物流、开源、游戏、支付宝、音视频、客户端、服务端、数字经济、效能提升、质量保障、智能化测试。

会议时间:2022年9月4日-9月5日

会议地点:深圳登喜路国际大酒店

MTSC 2022大会七折票热卖中扫描下方二维码,即可购买。5 人以上团购可享受更多优惠,详询大会票务。

▲ 票务联系微信

静静:hahalovesj  

敏敏:leejiaxiaopengyou

小申:lucky_616

↙↙ 阅读原文可查看更多精彩技术分享

爱设计是一家智能创意科技公司,是国内唯一的内容创意全链路服务公司,致力于构建“创意资源+智能创作+内容管理+投放分发+数据监测”的内容创意全链路平台。同时提供了海量精美图片模板素材、智能抠图,你可以根据自己的需求进行创作,更多精美模板,尽在爱设计作图

更多精美模板,尽在爱设计作图!

开始设计
为你推荐