应用办公生活信息教育商业
投稿投诉
商业财经
汽车智能
教育国际
房产环球
信息数码
热点科技
生活手机
晨报新闻
办公软件
科学动态
应用生物
体育时事

支付宝客户端OOM专项优化实践(安卓篇)

  一、背景:
  作为一名Android程序开发者,在日常的代码开发工作中可能不会过多关注自己业务对内存的使用是否合理,通常情况下Android系统的内存管理机制帮我们处理好了内存的分配和回收。然而在一些异常场景下不合理的内存占用不仅会使用户应用程序运行卡顿、ANR、黑屏,在极端情况下还会发生OOM(OutOfMemory)崩溃,极大影响用户体验造成用户流失。通常我们在对待线上的的OutofMemory的闪退都会被当做小概率事件没有被有效重视和系统分析,本文将结合支付宝线上OOM真实案例详细的介绍下常见OOM问题的根因分析和优化实践。
  在支付宝应用架构的不断演进中用户支付场景已经是最基础的使用场景,随着小程序生态的引入森林庄园等复杂h5小程序的使用比例不断增长,同时理财、本地生活等重度业务也运行在支付宝这艘航母上,并且在每年的大促活动像双11、618、新春五福活动上线后让本就不富裕的内存空间又雪上加霜,在2020年之前支付宝的内存问题一直未被重点关注,从一组数据可以看到在过去的1920财年中,客户端OOM闪退率暴涨了近一倍,占整体客户端闪退的45以上,内存水位则涨幅在300M左右,按照这个趋势20年底的OOM闪退率会涨幅50。那到底是什么原因导致的支付宝OOM问题如此严重呢?这里先抛出几个问题:线上低端机的OOM问题是否真的比高端机更严重呢?线上的OOM真的全是由于Java内存泄漏导致的堆内存紧张导致的吗?线上OOM有没有可能在App堆内存宽裕,设备物理内存也宽裕的情况下发生?二、OOM问题根因分析2。1OOM分类
  通过以下数据我们可以看到在支付宝32位包的OOM闪退中911系统的占比远远超过6。x以下机器,并且在对闪退时内存统计中发现5。x以上机器闪退时端上整体内存值还有大量剩余,而虚拟内存空间几乎达到了2324GB。
  众所周知32位应用程序的虚拟内存寻址上限只有2324GB,无论高端机还是低端机只要虚拟内存寻址达到这个上限就会触发系统OOM闪退,通常在logcat日志中会看到OutOfMemoryError:pthreadcreate(1040KBstack)failed:Tryagain,libcabi:terminatingwithuncaughtexceptionoftypeSt9badalloc:std::badalloc,Couldnotmmaphandle0x67ae34d0fd652(Outofmemory)等。因此按照不同的成因我们总结了OOM问题分类,只有对线上OOM问题清晰的认识和分类才能更好的感知问题变化和有针对性的治理
  2。2虚拟内存地址指标量化
  下面将会从虚拟内存结构入手详细地讲解一下导致虚拟内存寻址空间不足的原因,从下图内存结构看出去系统占据的1G外剩下3GB内存都是如何分配?通常我们在写Native代码的时候,并不会直接调用内核的API去申请物理内存,而是使用malloc族的函数进行内存申请,这时候返回的指针是指向虚拟内存中的地址空间,之后在这部分地址空间真的被使用的时候,才会发生缺页中断触发真实的物理内存分配,所以通常是两层分配结构,用户态的代码申请的内存来自于内存分配器的二次分配,常见的内存分配器有JeMalloc、TcMalloc、PtMalloc等等。这里也解答了上面的问题,手机物理内存或javaheap内存只使用不到50的情况下,虚拟内存可能已经打满同样会触发OOM闪退。
  三、线上监控问题感知
  那么虚拟内存的使用应该如何度量呢?简单的方式是直接从proc{pid}status文件读取vmsize数据,但如果要做到能感知线上内存水位变化并快速定位问题还需要更细粒度的分类。如上图所示,通过对proc{pid}maps地址文件的内存分配标记进行分类可量化成20个细粒度内存指标,在支付宝启动后的内存空间分析中可以看到在支付宝启动后留给业务的内存空间大概在12G左右,如果没有有效的内存监控释放手段,随着应用使用时长的增加,内存地址空间会被迅速耗尽。下面会介绍线上主要的几个内存监控方式。3。1支付宝全局虚拟内存水位监控
  基于虚拟内存的水位监控主要作用是感知活动或者开关变更导致的内存上涨,同时能确定业务维度的内存水位变化,通过制定告警阈值,让线上问题定位达到分钟级别。3。1。1典型案例:首页氛围图和腰封Lottie动画
  大促活动期间首页氛围图或腰封上线lottie动图引起的Libcmalloc上涨约涨2050M,导致OOM闪退率上涨30,相比业务上线活动首页氛围和腰封的变更影响是全局的基础水位,对OOM闪退率影响较大。下图为某次活动0点发布氛围后支付宝整体内存水位上涨40M。针对这一问题我们对所有lottie上线资源做了动态的内存检测,超过阈值则被禁止上线,同时通过线下的内存检测结果可预估lottie上线后对线上闪退率的影响
  0点活动上线内存水位上涨
  线上闪退率预估3。1。2典型案例:大促活动
  随着渲染技术迭代新春五福,双11活动的页面动画特效复杂度越来越高,已经不再局限于2D动画,并且活动页会为支付宝内其他业务引流,当用户不断跳转页面访问时内存可能不会及时释放,导致短时间的内存叠加效应引起内存水位升高同时OOM闪退率上涨。针对这一问题,支付宝活动都会针对渲染特效设计几种降级方式,在内存水位变化幅度超过阈值或OOM闪退率上涨情况下可以对业务进行统一降级,动画静态图,3D2D等
  3。1。3典型案例:Dexpatch
  Dexpatch发布引起的端整体PublicFile水位上涨50M左右,由于Dexpatch本身的实现方式要在native解包和替换,导致mmap了大量内存,目前在32位包已经不再使用Dexpatch热修复。下图是线下测试结果:
  3。1。4典型案例:uc内核解压
  uc压缩内核推动动态bundle,通过用户日志可以发现so解压后出现错误,导致用户重复进行初始化进而导致PublicFiles内存上涨后触发OOM闪退。在推送回滚后,整体崩溃率下降。3。1。5典型案例:蚂蚁庄园
  蚂蚁庄园3周年活动,生活号文章插入超大gif动图导致Gpu增幅超过300M引起线上OOM闪退告警,暴露了目前对于h5小程序中的大图、视频和动图没有提前发现的能力。基于这个问题在对业务准入的时候增加图片视频的静态尺寸检测和动态内存检测,避免类似问题再次发生。
  小程序H5中资源与内存使用关系梳理:高清大图内存主要分配在gpu上,随便下载了一些文章详情的图片发现大小都在1MB以内,这是因为图片都是有压缩的,但是在手机中图片显示是完全解压状态,正常情况图片的内存计算方式:png像素总数(图片宽高)4Byteperpixel13(渐进式、缩放缓存、纹理尺寸、mipmap限制等因子影响),因此高清大图应控制分辨率,按需使用适当尺寸的图片,禁止超高分辨率图片gif图片内存主要分配在gpu上,由于gif采用多帧轮播的方式播放,gif所有帧内存都会加载到gpu中且无法释放,其内存计算方式是:GIF像素总数(图片宽高)4Byteperpixel总帧数12(纹理尺寸、mipmap限制等因子影响)典型案例:分辨率6904746,帧数21,文件大小346KB直接占用GPU210MB,该图仅最上面是动图,而全图使用gif格式并且以超长图展示,线下测试手机需要至少10s才能加载出该图。应该严格限制此类情况发生
  3。2运行时业务维度内存异常监控
  在监控内存水位的同时,我们还要掌握每个业务生命周期内分配的内存空间是否合理,目前做法是通过开关配置一组内存指标异常值,当业务单次采样间隔内存分配超过阈值时上报相关数据,概数据帮助我们在线下推动业务对内存使用优化,同时配合线上告警机制保证业务内存使用变化时能快速感知到。典型案例:
  线上监控到某选图打印的小程序单次的Libcmalloc增幅超过300M,导致该应用OOM闪退率是正常业务的20倍,主要原因有2点:用户在使用小程序时会选择一张手机图片,在多媒体选图组件做图片预览和大图展示时为了加快图片展示提前加载了选图前后2张,由于图片加载内存全部分配在Native导致Libcmalloc内存大幅上涨,个别用户涨幅超过1G多媒体组件没有监听小程序退出事件,因此没有及时做内存回收导致缓存的图片数据长时间在内存中保存
  3。3闪退时刻的端上运行环境数据记录在内存问题排查中至关重要
  支付宝微镜平台提供了闪退issue的查看和分析能力,我们只需在客户端闪退时按照一定格式将端上运行时数据记录到埋点即可在平台查看到聚合后的数据临近闪退时的内存snapshot及闪退时刻内存数据记录,方便排查闪退前的内存变化趋势和闪退时内存数据聚合分析部分maps原始地址数据,隐藏了内存中异常信息完整的虚拟地址解析后结构,如下图MoudlesMoudlesAshmemMoudlesJavaVMMoudlesNativeAnonymousMoudlesNativeBssMoudlesNativeLibcMallocMoudlesNativeOtherMoudlesOtherPublicPublicDevicesPublicFilesPublicGpuPublicThreadsU4CoreU4CoreBlinkGCU4CorePartitionAllocU4CoreSharedMemoryU4CoreUCMallocU4CoreV8Heap典型案例:MIUIAndroid10系统字体重复占用虚拟内存,导致支付宝App可用的虚拟内存变少,更容易发生崩溃(发生OOM)。支付宝在20年的双十一活动的OOM中,小米红米机型占比43,高于小米手机的市占率某外卖小程序在使用v8worker的时候调用messageport发给render进程大量消息并使用了sharedmemory导致闪退率上涨
  四、内存诊断治理4。1Native内存问题治理
  支付宝是一个汇集了扫码,端智能,AR,小程序容器,音视频播放等native代码非常多的大型应用,据不完全统计有100个so在支付宝内运行,每个native代码相关的模块背后都有一个专业团队在高速迭代,Java堆内存因为有比较成熟的工具和方法论,加上hprof快照作为补充,定位和治理都很方便,native内存问题一直缺乏高效稳定的工具导致问题治理难度非常大。事实上,单纯的native内存泄漏问题相对较少,更多的是因为业务逻辑不合理带来的内存使用问题,需要工具渗透到App运行的过程中进行监控,对工具性能和稳定性提出更高的要求。
  因此对于支付宝的native内存泄漏监控工具的诉求主要有以下几个方面:接入成本:无需额外适配Android版本,无需root稳定性:几乎不影响业务的稳定性问题,可以满足灰度版本开启即可性能层面:对业务运行和启动都没有明显劣化影响,无卡顿和ANR问题监控范围:不局限于malloccallocreallocmemalignfree,至少还能覆盖mmapmmap64munmap支撑广度:内存监控,内存泄漏,野指针检测等1。工具调研
  维度产品
  SoAOP(支付宝)
  mallocdebug
  AddressSanitizer
  memhook(UC)
  NativeFinder(手淘)
  是否需要root
  不需要
  需要
  需要
  需要
  否
  功能支撑广度
  内存泄漏、So内存值监控、堆破坏、野指针
  内存泄漏、堆破坏、野指针
  内存泄漏、堆破坏、野指针、缓冲区溢出
  内存泄漏检测
  内存泄漏、堆破坏、野指针
  堆栈能力
  有
  有
  有
  有
  有
  性能
  好
  差
  好
  较好
  好
  接入成本
  低
  高
  高
  高
  较高2。技术方案
  支付宝的native内存泄漏监控工具主要包含三部分:代理实现、栈回溯和缓存管理,其中代理实现是对malloccallocreallocmemalignfree和mmapmmap64munmap等函数的hook,决定了hook的准确程度至关重要,这里我们选择了比较成熟的PLThook工具代表xHook,该方案已经在业内多个内存线上方案中使用,其稳定性可以达到上线标准。在栈回溯上使用了性能更好的libudf方案兼具了性能要求和回溯成功率,为了提高线上的使用场景,我们在使用时通过开关限制栈回溯频次
  方案细节:首先客户端在启动后会初始化注入hook相关的服务。通过轮询扫描procselfmaps获取支付宝包内的实时so数据,并添加so管理。hook的mallocfreemmapmunmapmmap64pthreadexitcallocrealloc监听方法回调,根据内存指针通过mallocusablesize方法获取对应的内存和so数据,进行统计内存。
  线下方案:
  目前线下方案通过动态bundle的方式可以扫码实时加载到支付宝客户端中,通过悬浮窗的方式展示内存数据和栈回溯信息,同时也支持接口和Logcat日志方式查看数据
  3。典型案例搜索引擎使用文件缓存聊天词汇提高搜索效率,在灰度版本中出现较多的索引文件导致虚拟内存异常升高,其中(libarmlibclientsearcher。somalloc103M)(filessearchalipaysearchallinidx0mmap188M)291M内存使用
  可以从maps的地址空间看到多个mmap的文件信息
  cube上层业务社交商家群页面如果快速进出页面未及时调用释放接口导致cubenative内存泄漏,cube业务本身缺少运行时的内存监控,对上游业务方的使用充分信任,导致这个灰度版本问题,在业务优化后修复
  4。2FD内存问题治理技术方案
  FDSETchk问题大多出现在Android7。1。2及之前版本原因是FD总数超过1024个导致,如下图所示大多在闪退堆栈中能看到FDSETchk标识。
  线上的FD的主要监控方式是在FD总数超过900后通过proc{pid}fd采集所有fd数据进行上报,并对FD名称进行聚合,以issue的形式在微镜平台展示,这样在某一类FD异常pv变化时就能找到相关变更点
  线下通过shell脚本方式可以进行测试注:如遇到commandnotfound,需要使用homebrew安装相应命令exportPKGcom。eg。android。AlipayGphonefunctionapid(){echo(adbshellpidofPKG)}Mac上watch命令需要使用homebrew安装(brewinstallwatch)watchn0。2dadbshellrunasPKGlslproc(apid)fdcutdf10sedEs〔09afAF〕{4,}xxxgsortuniqcsortnrhead10
  典型案例Gpu独立进程使用的Surface对象未主动释放,在部分手机出现FD泄漏导致闪退率上涨问题描述:
  主进程anoninode:syncfileFD泄漏的pv从1月24日9k上涨到2月3日50。7万,并且持续未恢复,syncfence和syncfencemalifence的issue趋势相同。问题定位:使用NDK提供的APIsyncfileinfosyncgetfenceinfo发现了关键字:gpuprocess,SurfaceTexture。线下测试关闭GPU独立进程后(开关h5ucgpuprocessmode0)不再出现泄漏issue上涨趋势大致与开启GPU独立进程的节奏同步根因分析:
  Gpu进程使用的Surface对象,其内部的SurfaceTexture来自TextureView,很多手机的实现都需要主动执行Surface。release()才能释放这个SurfaceTexture资源(待Surface对象被gcfinalize也会释放),原生实现未执行主动release导致SurfaceTexture泄漏,其native实现有申请syncfile等对象,导致fd泄漏。
  4。3CloseGuard资源泄露检测CloseGuard介绍
  系统代码预埋了一些检测点,检测需要手动释放却未释放的资源。分配资源时获取调用栈,并记录对应的关闭方法的名称,GC回收时在finalize()方法里检测是否释放过,没有释放则上报异常(不会crash)。原理可参考系统说明文档CloseGuard。
  常见的可以检测的资源泄漏:各种InputStreamOutputStream未closeandroid。view。Surface未releaseandroid。database。Cursor未closeandroid。app。usage。NetworkStats未close
  可以检测的资源依赖系统代码预埋。AndroidR起系统开放了接入接口,可以将自定义的资源纳入检测手动回收必要性
  系统在finalize里会回收,为什么还有手动回收?finalize回收是系统做的兜底,时机不确定,回收不及时会抬高内存峰值,当虚拟内存峰值接近4GB,再申请内存就会crash,即使以后能回收也晚了。未回收的资源背后可能是javahealp内存,CC分配的内存,FD,mmap,GPU,Bitmap等,不止会造成内存问题,还可能导致FD超限等问题线上监控
  目前已经将检测结果和缺陷平台打通,可以在版本灰度期间卡住新增的泄漏问题
  典型案例ZApacheSSLSocketFactorysocket泄露导致pipeFD泄露2021051414:29:12:801EmynetHttpWorker:〔5761:HttpManager。HttpWorkerh514〕processException,exceptionNameIOException,code〔6〕canRetry〔false〕e〔java。net。SocketException:Socketclosed〕java。net。SocketException:Socketclosedatcom。android。org。conscrypt。NativeCrypto。SSLdohandshake(NativeMethod)atcom。android。org。conscrypt。NativeSsl。doHandshake(NativeSsl。java:387)atcom。android。org。conscrypt。ConscryptFileDescriptorSocket。startHandshake(ConscryptFileDescriptorSocket。java:226)atcom。alipay。mobile。common。transport。ssl。ZApacheSSLSocketFactory。createSocket(ZApacheSSLSocketFactory。java:100079)atcom。alipay。mobile。common。transport。http。ZClientConnectionOperator。connect(ZClientConnectionOperator。java:100221)atcom。alipay。mobile。common。transport。http。ZClientConnectionOperator。openConnectionCustome(ZClientConnectionOperator。java:100108)atcom。alipay。mobile。common。transport。http。ZClientConnectionOperator。openConnection(ZClientConnectionOperator。java:100193)atorg。apache。http。impl。conn。AbstractPoolEntry。open(AbstractPoolEntry。java:170)atorg。apache。http。impl。conn。AbstractPooledConnAdapter。open(AbstractPooledConnAdapter。java:124)atorg。apache。http。impl。client。DefaultRequestDirector。execute(DefaultRequestDirector。java:366)atorg。apache。http。impl。client。AbstractHttpClient。execute(AbstractHttpClient。java:587)atcom。alipay。mobile。common。transport。http。AndroidHttpClient。execute(AndroidHttpClient。java:100002)atcom。alipay。mobile。common。transport。http。HttpWorker。doExecuteRequestByHttpClient(HttpWorker。java:100017)
  sslSocket。startHandshake中抛出异常导致sslSocket对象没有机会关闭publicclassZApacheSSLSocketFactoryimplementsLayeredSocketFactory{OverridepublicSocketcreateSocket(Socketsocket,Stringhost,intport,booleanautoClose)throwsIOException{SSLSocketsslSocket(SSLSocket)ZCustSSLSocketFactory。getSSLSocketFactory()。createSocket(socket,host,port,autoClose);。。。省略部分代码intsoTimeoutsocket。getSoTimeout();try{sslSocket。startHandshake();}finally{setSoTimeout(socket,soTimeout);}returnsslSocket;}}Inflaterokhttp。GzipSourceHttpURLConnection。getResponseCodejava。lang。Throwable:Explicitterminationmethodendnotcalledatdalvik。system。CloseGuard。open(CloseGuard。java:221)atjava。util。zip。Inflater。init(Inflater。java:114)atcom。android。okhttp。okio。GzipSource。init(GzipSource。java:62)atcom。android。okhttp。internal。http。HttpEngine。unzip(HttpEngine。java:473)atcom。android。okhttp。internal。http。HttpEngine。readResponse(HttpEngine。java:648)atcom。android。okhttp。internal。huc。HttpURLConnectionImpl。execute(HttpURLConnectionImpl。java:471)atcom。android。okhttp。internal。huc。HttpURLConnectionImpl。getResponse(HttpURLConnectionImpl。java:407)atcom。android。okhttp。internal。huc。HttpURLConnectionImpl。getResponseCode(HttpURLConnectionImpl。java:538)atcom。android。okhttp。internal。huc。DelegatingHttpsURLConnection。getResponseCode(DelegatingHttpsURLConnection。java:105)atcom。android。okhttp。internal。huc。HttpsURLConnectionImpl。getResponseCode(HttpsURLConnectionImpl。java:26)atcom。alipay。android。msp。framework。helper。FileHelper。a(FileHelper。java:43)
  原因:HttpURLConnection的getInputStream未closeDeflaterGZIPOutputStream。java。lang。Throwable:Explicitterminationmethodendnotcalledatdalvik。system。CloseGuard。open(CloseGuard。java:221)atjava。util。zip。Deflater。init(Deflater。java:181)atjava。util。zip。GZIPOutputStream。init(GZIPOutputStream。java:90)atjava。util。zip。GZIPOutputStream。init(GZIPOutputStream。java:109)atcom。alipay。mobile。mascanengine。imagetrace。ImageTracer。trace(ImageTracer。java:2161)
  原因:GZIPOutputStream未close导致Deflater未endGZIPOutputStream设计问题导致无法关闭Deflaterjava。lang。Throwable:Explicitterminationmethodendnotcalledatdalvik。system。CloseGuard。open(CloseGuard。java:237)atjava。util。zip。Deflater。init(Deflater。java:189)atjava。util。zip。GZIPOutputStream。init(GZIPOutputStream。java:90)atjava。util。zip。GZIPOutputStream。init(GZIPOutputStream。java:109)atorg。nanohttpd。protocols。http。response。Response。a(UnknownSource:29)atorg。nanohttpd。protocols。http。response。Response。send(UnknownSource:291)
  原因:GZIPOutputStream构造函数往socket写数据异常,导致Deflater没机会关闭java。net。SocketException:Brokenpipeatjava。net。SocketOutputStream。socketWrite0(NativeMethod)atjava。net。SocketOutputStream。socketWrite(SocketOutputStream。java:109)atjava。net。SocketOutputStream。write(SocketOutputStream。java:141)atorg。nanohttpd。protocols。http。response。ChunkedOutputStream。write(UnknownSource:25)atorg。nanohttpd。protocols。http。response。ChunkedOutputStream。write(UnknownSource:2)atorg。nanohttpd。protocols。http。response。MyOutputStream。write(UnknownSource:6)atjava。util。zip。GZIPOutputStream。writeHeader(GZIPOutputStream。java:182)atjava。util。zip。GZIPOutputStream。init(GZIPOutputStream。java:94)atjava。util。zip。GZIPOutputStream。init(GZIPOutputStream。java:109)atorg。nanohttpd。protocols。http。response。Response。a(UnknownSource:29)atorg。nanohttpd。protocols。http。response。Response。send(UnknownSource:291)
  解决方案:publicclassGzipOutputStreamWrapextendsGZIPOutputStream{publicGzipOutputStreamWrap(OutputStreamoutputStream,intsize)throwsIOException{super(newOutputStreamWrap(outputStream),size);if(this。outinstanceofOutputStreamWrap){OutputStreamWrapwrap(OutputStreamWrap)this。out;wrap。mCacheExceptionfalse;if(wrap。mCachedException!null){this。def。end();throwwrap。mCachedException;}}}staticclassOutputStreamWrapextendsFilterOutputStream{privatebooleanmCacheExceptiontrue;privateIOExceptionmCachedExceptionnull;publicOutputStreamWrap(OutputStreamout){super(out);}Overridepublicvoidwrite(intb)throwsIOException{if(mCacheException){try{super。write(b);}catch(IOExceptione){mCachedExceptione;}}else{super。write(b);}}Overridepublicvoidwrite(byte〔〕b,intoff,intlen)throwsIOException{if(mCacheException){try{super。write(b,off,len);}catch(IOExceptione){mCachedExceptione;}}else{super。write(b,off,len);}}Overridepublicvoidwrite(byte〔〕b)throwsIOException{if(mCacheException){try{super。write(b);}catch(IOExceptione){mCachedExceptione;}}else{super。write(b);}}}}五、内存优化方案
  在对内存问题治理的同时我们也在尝试进行支付宝运行时的内存优化,主要思路是通过内存监控进行全端的内存水位通知,让监听的业务方能结合自身情况给主进程释放更多的空间5。1全局内存通知降级客户端MemoryNotice监听查询级别定义MemoryLevel,用int表示,级别之间可直接比较大小Critical:内存水位很高,很容易OOMHigh:内存水位高,可能OOMNormal:内存水位正常监听接口finalAbnormalReqabnormalReqnewAbnormalReq();abnormalReq。typeMemoryNotice。class;Stability。getAbnormalDCApi()。registerAbnormalListener(newADCApi。AbnormalListener(){privatefinalSetrequestCollections。singleton(abnormalReq);OverridepublicSetaccepts(){returnrequest;}OverridepublicvoidonAbnormal(Abnormalabnormal){if(abnormalinstanceofMemoryNotice){intmemoryLevel((MemoryNotice)abnormal)。getMemoryLevel();switch(memoryLevel){caseMemoryNotice。MemoryLevel。Critical:释放内存。回调不在主线程执行break;}}}});主要监听业务:多媒体图片缓存服务,在内存紧张时可降低已缓存的图片内存数据Lottie内存释放,在首页腰封等展位通常使用Lottie动画展示动图,在内存紧张情况下可在首页不可见时降低缓存数据小程序容器会在Critical内存等级时提示用户当前使用的小程序可能出现异常,引导用户关闭小程序释放内存空间,避免主进程闪退Artmainspace内存空间释放监听了内存通知,当内存超过一定阈值时会触发内存压缩(详见下文)小程序业务统一降级,支付宝大促活动通常会接入统一降级能力,通过开关可直接对线上活动页的动画,特效,渲染方式等做降级,在端上内存不足时会触发统一降级的自动降级,达到降低业务内存使用的目的5。2ArtMainspace空间压缩技术方案:
  通常情况下,我们的应用都会开启largeHeap,来获得更大的内存上限,因为默认可用的空间只有192M,这是由参数dalvik。vm。heapgrowthlimit决定的,对于大部分集团应用来说显然是不够的,但是开启largeHeap之后实际可用则可达到512M10242,这也导致了应用启动的时候就会申请1G的地址空间,同样对于大部分应用来说,直到abort或者应用被杀死,都不会使用如此多的地址空间
  释放前Mainspace占有1G释放后Mainspace占有500M效果:
  500M内存对于32位包的OOM问题降低有非常大的作用,在线上的闪退率监控中使用Mainspace释放后的版本闪退率降低了305。3Gpu独立进程技术方案:gpu进程核心两个作用:
  1、剥离驱动兼容性问题到子进程,不要让他影响主进程
  2、降低内核渲染对主进程的资源依赖,降低主进程oom引入并适配GPU独立进程改造前:
  改造后:
  效果:
  在gpu独立进程全量开启后,线上日均8K的OOM闪退类型:GSLMEMERROR:kgslsharedmemallocioctlfailed和sharedmemgpumemalloc:mmapfailederrno12Outofmemory几乎清零。在2021年五福项目期间GPU独立进程使得支付宝Android整体闪退率下降了6573六、总结
  支付宝内存从2020年初开始治理优化,OOM闪退率从最开始的万分之0。84降低到万分之0。14,在线上问题感知上,内存水位和业务异常内存变化可在5分钟内感知到,在问题诊断定位上可达到半小时内定位具体业务和问题根因代码,H5小程序可在1天内修复好迭代发版。在新春五福红包等大促活动中峰值OOM闪退率也从万分之2降低到万分之0。3左右,极大的降低了客户端故障风险。
  内存优化实践大图
  同时我们总结了一套完整的内存优化实践方法论,本文主要针对线上能力和案例进行了分析,其实线下的问题定位和卡劣能力建设同样非常重要。1。线下IDE工具和泄漏检测工具建设
  线下定位和复现工具建设,包括线下的内存水位曲线监控工具,泄漏检测工具,端上实时内存数据展示等,能帮助我们在线下快速定位到问题根因,帮助业务修复2。版本发布内存劣化卡口
  在版本发布周期内对每日构建包进行大版本间的内存水位对比和泄漏检测,在版本发布维度将问题卡在线3。H5小程序及动画资源变更卡口
  制定业务资源和内存使用标准在业务开发阶段引入检测手段发现异常点并提示给前端开发。在H5小程序、Lottie等发布上线环节增加卡劣检测措施,提前发现内存问题
  目前支付宝在最近几个大版本平稳过渡到了64位包,64位应用的虚拟内存地址空间上限是239512GB,理论上看彻底解决了32位包的虚拟内存地址不足的问题,但是线上32位包用户占比仍有约10左右,短时间内都将保持双包并存,因此32位包用户的体验问题仍然不能放手不管。同时64位包升级后的Java堆内存不足问题和线程超限问题同样需要关注。面对支付宝庞大的线上用户和复杂的线上问题,64位升级远远不是终态,前方面临的挑战还有很多,时刻不松懈才能守住内存的底线。七、参考文献
  【手淘稳定性】Native治理利器NativeFinder
  Android32位应用NativeCrashTop1Abort的探索和解决
  链接2019年双十一AndroidU4内核OOM问题总结
  西瓜视频稳定性治理体系建设二:Raphael原理及实践
  GPU独立进程(进程隔离)
  八、本文作者
  安晴、推敲
  转自支付宝质量开放平台AnTest:
  https:antest。alipay。comecoqualitytblog01bwwe03eyb2

盘点十大高画质Steam的游戏,ATLAS新武器毒箭群伤效果以求生为题材的游戏一直以来都在市场上备受欢迎,每年也都有着不少这类题材的新游戏涌现,接下来就为大家在诸多生存游戏中筛选出几款必玩的,体验一下绝对不会踩雷。《ATLAS》……今日油价2022年10月9日9295汽油,柴油价格,明晚或油明晚12点(10月10日24时)将进行今年第19次油价调整,目前经过9个工作日的统计,预计油价上调15元吨,距离上调标准只差35元吨。大家相互转告,明晚油价有可能重新上涨了。……为何大罗的欧冠只有14粒进球?他到底经历了什么?说到大罗,喜欢他的球迷津津乐道,不仅大罗是他们的足球初恋那么简单,大罗的身体、技术、速度和视觉观感上都给喜欢他的球迷带来极大的震撼,在那个年代,只要看过大罗的比赛,就没有人不喜……小米12TPro与Redmi平板渲染图曝光手机主打2亿像素在推出了MIXFold2等新机后,小米又进入了新一轮的新机筹备工作,最近有外媒曝光了一张可能是小米12TPro智能手机与RedmiPad平板电脑的外观渲染图,看来这两款产品的发……击退来犯的罗马军团尼罗河勇士2自由决定冒险路线,选取技能石板强化角色,率领你的尼罗河勇士小队,击退来犯的罗马军团。作为一款继承初代回合制战棋肉鸽玩法的国产独立游戏,《尼罗河勇士2》带给我的体验可以用节……AI又攻破了一个被誉为人类护城河的领域美术似乎每隔一段时间,互联网就会被AI技术狠狠刷一波屏。从之前的下棋、翻译,到后来的写作、开车。相信许多网友都和机哥一样,已经对相关新闻见怪不怪了。然而,AI又双……国足无价之宝!扬科维奇赞不绝口,接手国足后必将重用,找对人了日前,扬科维奇带国足选拔队在东亚杯取得了一胜一平一负的不俗战绩。所以,球迷和媒体都呼吁他转正,未来接手中国国家队。对于,扬科维奇的转正前景,球迷还是觉得有些难测。毕竟,国足选择……我终于千粉了,写点感悟持之以恒,坚持不懈的日更,我赢得千粉,头条的创作翻开了新的篇章!看着收获的1001个粉丝,感慨万千。感谢粉丝一路陪伴,感谢相遇,感恩相知。感谢头条平台给我一个展示的机会,……托马斯你让乔丹去带领三支不同球队夺冠,我就承认他是历史第一坏男孩子军团大家是否记得,尤其是以托马斯为代表,托马斯认为,乔丹一直身边有皮蓬罗德曼库科奇才成全了他的战绩,如果他能像詹姆斯一样带领三支不同的球队夺冠,我就承认他就是历史第一。……冬日行【1】立冬日,步出小区,也走出了高楼林立下阴影。外面行人车辆稀少。暖融融的一片光照,太阳在碧蓝天空上柔和亮丽,万里无云,微风刚好吹动那树上的残留黄叶,走近也不闻一丝声响。……如果科学家将来证明鬼的存在,会对我们产生什么影响?这个世界上真的有鬼魂吗?科学界还没有对人死后会变成什么状态做出合理的科学解释。从心脏停止和大脑停止工作的那一刻起,我们默认进入了死亡状态。然而,没有人去过死后的世界,所以……越南华人女首富张美兰捐款5。7亿却突然被捕,惊动李嘉诚中国曾凭借着廉价的劳动力和材料,用第二产业的优势,将印有MadeinChina标记的商品送到了全世界人民的身边。可随着中国经济的发展,人民逐渐富裕,科技也在不断发展,作为……
<<<<<<>>>>>>
姆巴佩1。28亿美元登顶足坛球员收入排行,梅西C罗次之近日,福布斯公布了世界足球运动员2022年的收入排行榜,姆巴佩以1。28亿美元超越了梅西和C罗,成为了世界足坛年度收入最高的球员。姆巴佩在今年5月和巴黎圣日耳曼正式续约至……平潭岛旅游没有攻略只教避坑从平潭回来一周啦,缓了好几天,平潭真的真的很美,但是真的给我晒懵了,所以根据亲身经历,吐血整理出这份避雷攻略,要去平潭旅行的可作参考呀!首先最重要的是时间。虽然平潭……要想进步,就只有吸取教训1、要想进步,就只有吸取教训,成功的经验都是歪曲的,成功了,想怎么说都可以,失败者没有发言权,可是,你可以通过他的事例反思,总结。教训,不仅要从自己身上吸取,还要从别人身上吸取……孙红雷携娇妻走红毯,女方全程尬笑表现紧张,互动被网友调侃不熟21日,影帝孙红雷亮相某电影节,并且还带上了自己的小媳妇王俊迪。这二位很少一同出席活动,这次可谓是罕见的合体。在活动进行过程中,王俊迪一直跟在孙红雷身后,显得有些紧张,轮……10月份采购经理指数有所回落经济恢复发展基础需进一步稳固10月31日,国家统计局服务业调查中心、中国物流与采购联合会发布的中国采购经理指数(PMI)显示,10月份,受疫情多发散发等影响,中国采购经理指数有所回落,其中制造业采购经理指……电视盒子哪款好?工程师推荐目前最强的电视盒子对我们普通消费者来说8K貌似是很遥远的事情,毕竟现在智能电视的主流配置是4K分辨率,8K具有76804320分辨率的超精细画面,能带给人震撼的视觉享受,很多电视盒子已经开始支持……完美世界会抛弃CSGO吗?这就得看看完美世界的想法了可能看到这个标题,不少人已经按捺不住喷我的那个事情了,但你还别说啊,你们看看完美世界代理国服那么久的时间里面,CSGO的数据起来了吗?五年时间了,隔壁穿越火线都更新好几轮了,的……2022年最新冲牙器热门品牌排行统计公布最近蓝鲸咨询公布了2022年最新冲牙器热门品牌排行榜,这一次榜单主要考量品牌销量、热度、口碑等方面的数据,而不是单纯将销量作为评价标准!这样相对客观的数据统计能够避免刷榜刷单、……广东陶瓷企业成大湾区潮流达人来源:【消费日报】一桥连三地天堑变通途。临近国庆,对于想去香港、澳门游玩的人来说,55公里长的港珠澳大桥是热门的旅行体验选项。鲜为人知的是,在这项超级工程背后,有着许多广……江苏险胜辽篮,李楠赢球很高兴!杨鸣怀念刘志轩,弗格力挺丛明晨我们都知道今年新赛季江苏两支球队势头非常猛,李楠带领的江苏男篮和西热力江带领的同曦男篮刮起了一股风暴,席卷整个联赛!江苏男篮今天又赢球了,而且是战胜卫冕冠军辽宁男篮,取得……人民币涨近1000点,首套房贷利率下调,国庆节买房划算还是春一、人民币涨近1000点,首套房贷利率下调,国庆节买房划算还是春节?在传统房市营销旺季,有金三银四和金九银十这两个时点;这通常是开发商一年中最优惠活动的时候;对于买家来说……四年终圆梦!辽宁10082战胜广厦,队史第二次获得总冠军记者冯子涵这个夜晚,属于辽宁。4月26日晚,辽宁和广厦决战CBA总决赛第四场。此役,广厦再次变阵,李金效进入首发五虎,孙铭徽也继续带伤出战。最终,阵容更深的辽宁以100:……
友情链接:快好找快生活快百科快传网中准网文好找聚热点快软网