騰訊技術分享:Android版手機QQ的緩存監控與優化實踐

本文內容整理自公衆號騰訊Bugly,感謝原做者的分享。php

一、問題背景

對於Android應用來講,內存向來是比較重要的性能指標。內存佔用太高,會影響應用的流暢度,甚至引起OOM,很是影響用戶體驗。所以,內存優化也向來是行業內的重點工做項和難點工做項。html

手Q在很早以前就開發了不少內存優化技術:android

1)自研內存泄露檢測系統 LeakInspector天網:程序員

LeakInspector是一套完整內存泄露檢測系統:可以自動檢測應用內存泄露問題;並提供兜底回收以及自動提單功能;數據庫

2)圖片引用大圖告警:緩存

可以自動檢測出業務圖片不合理使用:好比解碼的圖片尺寸大於顯示尺寸2倍以上等問題。推進業務進行專項優化;安全

3)內存觸頂監控:微信

可以檢測出內存不足時佔用內存較高的業務場景,並定位到相應的頁面,推進業務進行優化。網絡

以上這些技術都取得了很好的內存優化效果,但他們的特色是:主要針對明顯的內存問題,缺乏更深刻的內存分析。數據結構

所以,手Q內存問題也一直存在,主要表如今如下兩方面:

1)手Q的平均內存一直持續增加,版本間增幅較高,手Q一月一個版本,平均每版本增加大概5.3M;

2)用戶的OOM率大概0.1%。

此次咱們主要從監控和清理兩個角度出發,系統化的進一步優化手Q內存: 

1)統一緩存監控:開發實現全面的內存緩存監控系統,可以更細緻的監控手Q內存緩存使用狀況,及時發現輕度不合理問題,推動優化;

2)內存清理 在監控的基礎上,開發實現自動清理機制:一方面統一調度手Q各業務主動清理內存,另外一方面,經過深刻的技術研究,實現系統內存清理技術。

經過監控和清理相互配合,咱們最終實現了優化手Q總體內存,下降OOM率的效果。如下是詳細方案。

學習交流:

- 即時通信開發交流羣:320837163[推薦]

- 移動端IM開發入門文章:《新手入門一篇就夠:從零開發移動端IM

(本文同步發佈於:http://www.52im.net/thread-1524-1-1.html

二、相關文章

騰訊技術分享:Android手Q的線程死鎖監控系統技術實踐

微信團隊原創分享:iOS版微信的內存監控系統技術實踐

微信團隊原創分享:Android內存泄漏監控和優化技巧總結》 

QQ音樂團隊分享:Android中的圖片壓縮技術詳解(上篇)

QQ音樂團隊分享:Android中的圖片壓縮技術詳解(下篇)

Android版微信安裝包「減肥」實戰記錄》 

iOS版微信安裝包「減肥」實戰記錄》 

微信客戶端團隊負責人技術訪談:如何着手客戶端性能監控和優化

三、統一緩存監控

統一緩存監控主要包含圖片緩存監控和業務對象緩存監控兩部分:

1)圖片緩存監控主要關注Bitmap的引用,定位圖片問題;

2)業務對象緩存監控,主要監控手Q各業務對象緩存,及時發現緩存問題。

3.1圖片緩存監控

對於Android應用來講,Bitmap向來是內存的佔用大戶。在手Q中平均有300+ Bitmap對象。

統計顯示:Bitmap引用內存佔手Q總內存40%左右:

 

 

減小圖片佔用內存,須要規範圖片緩存的使用。前期咱們在手Q中封裝實現了圖片專用多級緩存QQLruChe,並要求各業務必須使用全局圖片專用緩存來緩存圖片。一方面能夠方便調控圖片緩存業務,另外一方面,經過淘汰以及清理策略,能夠有效控制圖片緩存大小。但因爲手Q業務衆多,業務獨立開闢圖片緩存的狀況仍是時有發生。所以咱們開發了一套圖片緩存監控系統,及時檢測出圖片緩存私藏問題,同時也監控圖片的其餘不合理使用。

圖片緩存監控使用內存快照技術實現,分爲終端數據採集和後臺數據分析兩部分。

流程以下所示:

 

 

終端數據採集:客戶端實時檢測當前可用內存,當可用內存不足時,自動生成內存快照文件,上報到後臺。

後臺數據分析:在後臺,咱們實現了一套Hprof文件分析以及Bitmap引用歸併技術,批量分析內存快照文件,輸出Bitmap引用鏈並進行歸類統計,過濾全局圖片專用緩存以及View層引用後,分析出存在圖片緩存私藏的業務。

實現圖片緩存監控過程當中咱們主要遇到如下幾個難點:

1)內存快照文件大,約300M左右:

內存文件過大會致使上傳流量和存儲成本比較大,並且上傳耗時長。針對這個問題,一方面,咱們對大盤用戶採樣上報,並提供良好的用戶交互。另外一方面咱們深刻分析內存快照採集原理,自研miniDump工具,經過native hook技術在生成內存快照時剔除了tyte[]數據,從而使文件體積減小70%;

2)內存快照文件人工分析成本高:

經過MAT人工分析內存快照文件耗時費力,並且分析數量有限,用戶上報的內存文件不少,沒法定位top問題。針對該問題,咱們深刻研究MAT插件技術,自研引用鏈分析以及Bitmap引用歸併工具,自動化分析內存快照文件,歸類Bitmap圖片引用。

經過圖片監控系統,咱們有效檢測出如下幾類業務問題:

1)全局圖片專用緩存佔用空間大,存在優化空間:

bitmap引用鏈歸併發現全局圖片專用緩存佔較高。同時,咱們也統計了OOM用戶全局圖片緩存的內存量,平均約10M左右。所以有必要在內存不足時,自動trimToSize,釋放內存空間;

2)業務bug——邏輯完成後,沒有及時釋放圖片引用:

業務邏輯存在問題,好比有幾類業務在頁面退出後,沒有及時釋放背景圖資源引用;

3)業務私自開闢圖片緩存:

業務獨立開闢緩存cache緩存bitmap,沒有使用全局圖片專用緩存;

4)業務緩存數據對象中引用圖片:

業務內存緩存的數據對象中,含有bitmap成員,內存空間大。可優化爲緩存key,bitmap對象存到全局圖片專用緩存中;

5)圖片靜態引用:

定義靜態的Bitmap或者Drawable對象,進程週期內,對象所引用的資源都沒法釋放。

在手Q730版本,圖片緩存監控系統檢測出32例業務問題,提單26例,累計節省內存約23M。

3.2業務對象緩存監控

業務對象緩存監控主要是經過實現自定義集合類,實時上報各業務內存緩存使用狀況到後臺。在後臺分析歸併,從而定位業務緩存問題。

 

 

如上圖所示,業務對象緩存主要分爲終端數據採集、後臺數據分析、緩存清理三部分:

終端數據採集: 經過自定義實現QQHashMap,QQConCurrentHashMap,QQLruCache等集合類,在系統原有集合類基礎上,封裝統計功能,實時統計程序運行期間各緩存的內存指標:插入次數,查詢次數,刪除次數,遍歷次數,命中次數,未命中次數,緩存使用率,內存佔用等;

後臺分析:分析終端上報的用戶數據,對各業務緩存進行歸類統計,統計出平均內存佔用,最大內存佔用,內存佔用中位數,緩存命中率,緩存浪費率等指標;

內存清理:監控系統在監控的基礎上,也增長了清理接口。當檢測到當前可用堆內存比較低,用戶處於內存高負荷狀態時,統一調度清理邏輯,進行內存自清理優化。

經過統一緩存監控,咱們檢測出了不少業務緩存問題,主要可歸爲如下三類。

1)緩存浪費率高:

典型案例1:手Q表情某類緩存,平均浪費率超過88%,至關於緩存1000個對象,有800+沒有使用過;

典型案例2:某紅包模板緩存,存儲後從不訪問,浪費率100%。

針對這類問題,推進業務優化內存緩存結構,去除無用緩存,優化緩存方案,以下降浪費率。

2)緩存內存佔用大:

典型案例1:手Q某新聞類圖片緩存,私自緩存Bitmap,最大佔用內存15M,佔全部圖片緩存的35%;

典型案例2:錢包類背景圖緩存,內存佔用約1M左右,使用後未及時釋放。

針對這類問題,對於緩存圖片的業務,推進業務接入全局圖片專用緩存;對於非圖片類業務,接入自動清理,及時釋放內存空間。

3)緩存結構存在優化空間:

典型案例1:討論組成員緩存,設計爲LRUCache可淘汰緩存,可是用戶不曾用滿過。初始開闢空間過大;

典型案例2:未讀消息緩存,極端用戶緩存個數超過9000個,無數量上限控制。

針對這類問題,推進業務更新或者優化緩存結構,增長上限控制等。

四、內存清理

統一監控,能夠有效發現業務緩存問題進行專項優化。但監控具備必定的滯後性,所以在監控的基礎上,咱們同時也增長了內存清理控制模塊。

內存清理主要分爲業務內存清理以及系統內存清理。業務內存清理,包含統一圖片緩存清理,以及業務緩存對象清理兩部分。這裏前文已簡單介紹。接下來咱們介紹下兩例系統相關的內存清理技術:系統ClassLoader內存清理和系統預加載圖片清理。

4.1系統ClassLoader內存清理

前期,咱們分析了不少內存快照,發現一個共性的問題:在內存快照中有個ZipFile對象,內存佔用一直超過2.6M。這個zipFile被系統類ClassLoader引用。

 

 

經過分析系統源碼,咱們發現ZipFile記錄了安裝包全部的類文件信息,手Q安裝包中有超過15000個文件,文件越多,zipFile佔用內存就越大。

 

 

咱們進一步分析ClassLoader相關源碼,發現只有在調用ClassLoader的findResource方法查找圖片等安裝包內資源時,纔會使用到ZipFile的內容,未發現其餘使用場景。同時,經過findResource方式查找資源存在必定的弊端:耗時很長,在Android系統上不推薦使用。

詳情分析可參考:

http://blog.nimbledroid.com/2016/04/06/slow-ClassLoader.getResourceAsStream-zh.html

綜合評估,能夠清理ClassLoader引用的這塊內存。

清理主要面臨如下幾個難點:

1)Android系統碎片化嚴重,兼容性問題比較突出:

不一樣版本,zipFIle成員變量的位置以及變量名不一樣。zipFile初始化時機改變:4.3之前建立時即初始化,4.3以後,第一次訪問纔會初始化。各廠商對系統API內部修改沒法預期;

2)強行清理,可能致使功能異常:

系統內部代碼邏輯可能會受到影響,並且影響沒法預期。手Q當前使用ClassLoader查找資源的業務功能會受到影響。後期新增業務沒法預期,清理會致使系統功能失效;

3)清理後再次加載zipFile耗時長,可能致使卡頓。

下圖是咱們清理系統ClassLoader的實現方案,採用代理,兜底,緩存,上報等手段逐一攻克以上難點,完美實現清理系統ClassLoader內存的效果。

 

 

1)針對兼容性問題,咱們經過反射代理替換了系統的ZipFile爲HookZipFile,替換完成後,清理掉zipFile內存。替換機制兼容系統不一樣版本以及特殊機型,對系統邏輯無影響。

2)針對清理致使的功能異常,咱們實現了兜底能力,下次訪問時,會從新建立zipFile。

3)針對耗時問題,內部封裝實現緩存功能。並針對業務訪問增長堆棧上報,及時推進業務改用其餘方式獲取資源。

內存清理方案,經過內部兼容性測試,發佈後外網無crash問題,經過不斷迭代,兼容率達到100%。而且內存清理效果明顯,平均清理內存量約2.6M。

4.2系統預加載圖片清理

系統預加載圖片緩存是zygote進程初始化時,經過preloadResources()預加載的通用圖片資源,後續android應用進程都是從Zygote fork出來的,因此就繼承了這部分預加載的圖片資源。因爲是靜態強引用,這部分圖片資源會一直佔用內存空間。

 

 

預加載的好處在於系統只在zygote執行一次加載操做,全部應用用到該資源不須要再從新加載,減小資源加載耗時。與此同時,sPreloadedDrawables屬於靜態對象,會一直引用圖片緩存,因此該系統機制會佔用較高內存,在有些系統上,內存佔用空間超過20M。

所以這裏存在內存優化的空間,當內存佔用高時,能夠主動清理掉這部份內存,以便釋放可觀的堆內存空間,減小內存耗盡的風險。經過分析drawable加載機制的源碼,咱們瞭解到若是預加載的資源沒有在sPreloadedDrawables中找到,會從新decode解碼加載,不會影響現有功能。

所以清理後的風險可控,主要面臨的難點是兼容性問題:

1)系統API變更較多:

sPreloadDrawables數據結構類型,對象存儲位置,不一樣API版本之間都有改動;

2)廠商自定義修改較多:

好比:小米7.0系統以及華爲部分機型各自擴展了ResourceImpl實現,自定義了本身的資源加載基類,致使沒法定位到sPreloadDrawable;OPPO部分機型,修改了sPreloadDrawable類的屬性等等。

下圖是咱們清理系統預加載圖片緩存的實現方案,經過反射替換的方式,攔截替換系統的預加載緩存爲自定義圖片緩存,內部管理圖片加載,在內存不足時,及時清理預加載圖片緩存。

 

 

針對兼容性問題,咱們實現了一套完備的兼容性方案:

1)替換前兼容檢測;

2)系統版本兼容處理;

3)特定機型兼容處理;

4)失敗上報統計,不斷兼容。

系統預加載圖片清理,經過不斷迭代,已經能夠兼容幾乎全部機型。版本發佈後,未引入系統功能異常以及外網crash問題。內存清理量比較可觀:平均在15M左右,最高達到25M。

五、優化後的效果

5.1橫向對比

在灰度階段,咱們對用戶進行了ABTest測試,一半用戶接入內存優化邏輯,一半用戶不接入。大盤上報統計顯示:優化用戶OOM率明顯低於未優化用戶:OOM率由0.09%降至0.053%。

 

內存分佈方面,內存優化顯著下降了高內存用戶佔比。由3.05%降至1.7%。高內存用戶是指當前可用內存不足20%的用戶,是OOM高發用戶羣,下降這部分用戶比例,可有效下降OOM率。

 

5.2縱向對比

咱們從7.3.0版本接入內存優化,從版本迭代來看,優化效果顯著:OOM率由0.09%左右下降至0.047%左右,降幅47%:

 

手Q版本間平均內存增幅明顯放緩,版本增幅由5.8M左右降至1.14M左右:

 

附錄:更多微信、QQ的文章彙總

[1] QQ、微信團隊原創技術文章:

騰訊技術分享:Android版手機QQ的緩存監控與優化實踐

微信團隊分享:iOS版微信的高性能通用key-value組件技術實踐

微信團隊分享:iOS版微信是如何防止特殊字符致使的炸羣、APP崩潰的?

讓互聯網更快:新一代QUIC協議在騰訊的技術實踐分享

iOS後臺喚醒實戰:微信收款到帳語音提醒技術總結

騰訊技術分享:社交網絡圖片的帶寬壓縮技術演進之路

微信團隊分享:視頻圖像的超分辨率技術原理和應用場景

微信團隊分享:微信每日億次實時音視頻聊天背後的技術解密

騰訊團隊分享:手機QQ中的人臉識別酷炫動畫效果實現詳解

騰訊團隊分享 :一次手Q聊天界面中圖片顯示bug的追蹤過程分享

微信團隊分享:微信Android版小視頻編碼填過的那些坑》 

微信手機端的本地數據全文檢索優化之路》 

企業微信客戶端中組織架構數據的同步更新方案優化實戰

微信團隊披露:微信界面卡死超級bug「15。。。。」的前因後果

QQ 18年:解密8億月活的QQ後臺服務接口隔離技術

月活8.89億的超級IM微信是如何進行Android端兼容測試的

以手機QQ爲例探討移動端IM中的「輕應用」

一篇文章get微信開源移動端數據庫組件WCDB的一切!

微信客戶端團隊負責人技術訪談:如何着手客戶端性能監控和優化

微信後臺基於時間序的海量數據冷熱分級架構設計實踐

微信團隊原創分享:Android版微信的臃腫之困與模塊化實踐之路

微信後臺團隊:微信後臺異步消息隊列的優化升級實踐分享

微信團隊原創分享:微信客戶端SQLite數據庫損壞修復實踐》 

騰訊原創分享(一):如何大幅提高移動網絡下手機QQ的圖片傳輸速度和成功率》 

騰訊原創分享(二):如何大幅壓縮移動網絡下APP的流量消耗(下篇)》 

騰訊原創分享(二):如何大幅壓縮移動網絡下APP的流量消耗(上篇)》 

微信Mars:微信內部正在使用的網絡層封裝庫,即將開源》 

如約而至:微信自用的移動端IM網絡層跨平臺組件庫Mars已正式開源》 

開源libco庫:單機千萬鏈接、支撐微信8億用戶的後臺框架基石 [源碼下載]》 

微信新一代通訊安全解決方案:基於TLS1.3的MMTLS詳解》 

微信團隊原創分享:Android版微信後臺保活實戰分享(進程保活篇)》 

微信團隊原創分享:Android版微信後臺保活實戰分享(網絡保活篇)》 

Android版微信從300KB到30MB的技術演進(PPT講稿) [附件下載]》 

微信團隊原創分享:Android版微信從300KB到30MB的技術演進》 

微信技術總監談架構:微信之道——大道至簡(演講全文)

微信技術總監談架構:微信之道——大道至簡(PPT講稿) [附件下載]》 

如何解讀《微信技術總監談架構:微信之道——大道至簡》

微信海量用戶背後的後臺系統存儲架構(視頻+PPT) [附件下載]

微信異步化改造實踐:8億月活、單機千萬鏈接背後的後臺解決方案》 

微信朋友圈海量技術之道PPT [附件下載]》 

微信對網絡影響的技術試驗及分析(論文全文)》 

一份微信後臺技術架構的總結性筆記》 

架構之道:3個程序員成就微信朋友圈日均10億發佈量[有視頻]》 

快速裂變:見證微信強大後臺架構從0到1的演進歷程(一)

快速裂變:見證微信強大後臺架構從0到1的演進歷程(二)》 

全面總結iOS版微信升級iOS9遇到的各類「坑」》 

微信團隊原創資源混淆工具:讓你的APK立減1M》 

微信團隊原創Android資源混淆工具:AndResGuard [有源碼]》 

移動端IM實踐:iOS版微信界面卡頓監測方案》 

微信「紅包照片」背後的技術難題》 

移動端IM實踐:iOS版微信小視頻功能技術方案實錄》 

移動端IM實踐:Android版微信如何大幅提高交互性能(一)

移動端IM實踐:Android版微信如何大幅提高交互性能(二)

移動端IM實踐:實現Android版微信的智能心跳機制》 

移動端IM實踐:WhatsApp、Line、微信的心跳策略分析》 

移動端IM實踐:谷歌消息推送服務(GCM)研究(來自微信)

移動端IM實踐:iOS版微信的多設備字體適配方案探討》 

信鴿團隊原創:一塊兒走過 iOS10 上消息推送(APNS)的坑

騰訊信鴿技術分享:百億級實時消息推送的實戰經驗

>> 更多同類文章 ……

[2] 有關QQ、微信的技術故事:

技術往事:微信估值已超5千億,雷軍曾有機會收編張小龍及其Foxmail

QQ和微信兇猛成長的背後:騰訊網絡基礎架構的這些年

閒話即時通信:騰訊的成長史本質就是一部QQ成長史

2017微信數據報告:日活躍用戶達9億、日發消息380億條

騰訊開發微信花了多少錢?技術難度真這麼大?難在哪?

技術往事:創業初期的騰訊——16年前的冬天,誰動了馬化騰的代碼》 

技術往事:史上最全QQ圖標變遷過程,追尋IM巨人的演進歷史》 

技術往事:「QQ羣」和「微信紅包」是怎麼來的?》 

開發往事:深度講述2010到2015,微信一路風雨的背後》 

開發往事:微信千年不變的那張閃屏圖片的由來》 

開發往事:記錄微信3.0版背後的故事(距微信1.0發佈9個月時)》 

一個微信實習生自述:我眼中的微信開發團隊

首次揭祕:QQ實時視頻聊天背後的神祕組織

>> 更多同類文章 ……

(本文同步發佈於:http://www.52im.net/thread-1524-1-1.html

相關文章
相關標籤/搜索