日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 运维知识 > Android >内容正文

Android

微信 Android 终端内存优化实践

發(fā)布時(shí)間:2024/1/8 Android 40 豆豆
生活随笔 收集整理的這篇文章主要介紹了 微信 Android 终端内存优化实践 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

前言

內(nèi)存問(wèn)題是軟件領(lǐng)域的經(jīng)典問(wèn)題,平時(shí)藏得很深,在出現(xiàn)問(wèn)題之前沒(méi)太多征兆。而一旦爆發(fā)問(wèn)題,問(wèn)題來(lái)源的多樣、不易重現(xiàn)、現(xiàn)場(chǎng)信息少、難以定位等困難,就會(huì)讓人頭疼不已。

?

微信在過(guò)去 N 多的版本迭代中,經(jīng)歷了各式各樣的內(nèi)存問(wèn)題,這些問(wèn)題包括但不限于 Activity 的泄漏、Cursor 未關(guān)閉、線程的過(guò)度使用、無(wú)節(jié)制的創(chuàng)建緩存、以及某個(gè) so 庫(kù)悄無(wú)聲息一點(diǎn)點(diǎn)的泄漏內(nèi)存,等等。有些問(wèn)題甚至曾倒逼著我們改變了微信的架構(gòu)(2.x 時(shí)代 webview 內(nèi)核泄露催生了微信多進(jìn)程架構(gòu)的改變)。時(shí)至今日微信依然偶爾會(huì)受到內(nèi)存問(wèn)題的挑戰(zhàn),在持續(xù)不斷的版本迭代中,總會(huì)有新的問(wèn)題被引入并潛藏著。

?

在解決各種問(wèn)題的過(guò)程中,我們積累了一些相對(duì)有效和多面的優(yōu)化手段及工具,從監(jiān)控上報(bào)到開(kāi)發(fā)階段的測(cè)試檢查,為預(yù)防和解決問(wèn)題提供幫助,并還在不斷的持續(xù)改進(jìn)。本文打算介紹一下這些工程上的優(yōu)化實(shí)踐經(jīng)驗(yàn),希望對(duì)大家有一些參考價(jià)值。

?

Activity 泄露檢測(cè)

Activity 泄漏,即因?yàn)楦鞣N原因?qū)е?Activity 被生命周期遠(yuǎn)比該 Activity 長(zhǎng)的對(duì)象直接或間接以強(qiáng)引用持有,導(dǎo)致在此期間 Activity 無(wú)法被 GC 機(jī)制回收的問(wèn)題。與其他對(duì)象泄漏相比,Android 上的 Activity 一方面提供了與系統(tǒng)交互的 Context,另一方面也是用戶與 App 交互的承載者,因此非常容易意外被系統(tǒng)或其他業(yè)務(wù)邏輯作為一個(gè)普通的工具對(duì)象長(zhǎng)期持有,而且一旦發(fā)生泄漏,被牽連導(dǎo)致同樣被泄漏的對(duì)象也會(huì)非常多。此外,由于這類問(wèn)題在大量爆發(fā)之前除了 App 內(nèi)存占用變大之外并沒(méi)有 crash 之類的明顯征兆,因此在測(cè)試階段主動(dòng)檢測(cè)、排查 Activity 泄漏,避免線上出現(xiàn) OOM 或其他問(wèn)題就顯得非常必要了。

?

早期我們?cè)ㄟ^(guò)自動(dòng)化測(cè)試階段在內(nèi)存占用達(dá)到閾值后自動(dòng)觸發(fā) Hprof Dump,將得到的 Hprof 存檔后由人工通過(guò) MAT 進(jìn)行分析。在新代碼提交速度還不太快的時(shí)候,這樣做確實(shí)也能湊合著解決問(wèn)題,但隨著微信新業(yè)務(wù)代碼越來(lái)越多,人工排查后反饋給各 Activity 的負(fù)責(zé)人,各負(fù)責(zé)人修復(fù)之后再人工確認(rèn)一遍是否已經(jīng)修復(fù),這個(gè)過(guò)程需要反復(fù)的情況也越來(lái)越多,人工解決的方案已力不從心。

?

后來(lái)我們嘗試了 LeakCanary。這款工具除了能給出可讀性非常好的檢測(cè)結(jié)果外,對(duì)于排查出的問(wèn)題,還會(huì)展示開(kāi)源社區(qū)維護(hù)的解決方案,在 Activity 泄漏檢測(cè)、分析上完全可以代替人力。唯一美中不足的是 LeakCanary 把檢測(cè)和分析報(bào)告都放到了一起,流程上更符合開(kāi)發(fā)和測(cè)試是同一人的情況,對(duì)批量自動(dòng)化測(cè)試和事后分析就不太友好了。

?

為此我們?cè)?LeakCanary 的基礎(chǔ)上研發(fā)了一套 Activity 泄漏的檢測(cè)分析方案 —— ResourceCanary,作為我們內(nèi)部質(zhì)量監(jiān)控平臺(tái) Matrix 的一部分參與到每天的自動(dòng)化測(cè)試流程中。與 LeakCanary 相比 ResourceCanary 做了以下改進(jìn):

?

事實(shí)上這兩部分本來(lái)就可以獨(dú)立運(yùn)作,檢測(cè)部分負(fù)責(zé)檢測(cè)和產(chǎn)生 Hprof 及一些必要的附加信息,分析部分處理這些產(chǎn)物即可得到引發(fā)泄漏的強(qiáng)引用鏈。這樣一來(lái)檢測(cè)部分就不再和分析、故障解決相耦合,自動(dòng)化測(cè)試由測(cè)試平臺(tái)進(jìn)行,分析則由監(jiān)控平臺(tái)的服務(wù)端離線完成,再通知相關(guān)開(kāi)發(fā)同學(xué)解決問(wèn)題。三者互不打斷對(duì)方進(jìn)程,保證了自動(dòng)化流程的連貫性。

  • 分離檢測(cè)和分析兩部分邏輯。

?

  • 裁剪 Hprof 文件,降低后臺(tái)存檔 Hprof 的開(kāi)銷。

就 Activity 泄漏分析而言,我們只需要 Hprof 中類和對(duì)象的描述和這些描述所需的字符串信息,其他數(shù)據(jù)都可以在客戶端就地裁剪。由于 Hprof 中這些數(shù)據(jù)比重很低,這樣處理之后能把 Hprof 的大小降至原來(lái)的 1/10 左右,極大降低了傳輸和存儲(chǔ)開(kāi)銷。

?

實(shí)際運(yùn)行中通過(guò) ResourceCanary,我們排查了一些非常典型的泄漏場(chǎng)景,部分列舉如下:

?

  • 匿名內(nèi)部類隱式持有外部類的引用導(dǎo)致的泄漏

?

?

public?class?ChattingUI?extends?MMActivity?{@Overrideprotected?void?onCreate(Bundle?savedInstanceState)?{super.onCreate(savedInstanceState);setContentView(R.layout.activity_chatting_ui);EventCenter.addEventListener(new?IListener<IEvent>()?{//?這個(gè)?IListener?內(nèi)部類里有個(gè)隱藏成員?this$?持有了外部的?ChattingUI@Overridepublic?void?onEvent()?{//?...}});}}public?class?EventCenter?{//?此?ArrayList?實(shí)例的生命周期為?App?的生命周期private?static?List<IListener>?sListeners?=?new?ArrayList();public?void?addEventListener(IListener?cb)?{//?ArrayList?對(duì)象持有?cb,cb.this$?持有?ChattingUI,導(dǎo)致?ChattingUI?泄漏sListeners.add(cb);}}

?

  • 各種原因?qū)е碌姆醋?cè)函數(shù)未按預(yù)期被調(diào)用導(dǎo)致的Activity泄漏

?

  • 系統(tǒng)組件導(dǎo)致的 Activity 泄漏,如 LeakCanary 中提到的 SensorManager 和 InputMethodManager 導(dǎo)致的泄漏。

?

還有特別耗時(shí)的 Runnable 持有 Activity,或者此 Runnable 本身并不耗時(shí),但在它前面有個(gè)耗時(shí)的 Runnable 堵塞了執(zhí)行線程導(dǎo)致此 Runnable 一直沒(méi)機(jī)會(huì)從等待隊(duì)列里移除,也會(huì)引發(fā) Activity 泄漏等等。從來(lái)源上這類例子是舉不完的,總之任何能構(gòu)造長(zhǎng)期持有 Activity 的強(qiáng)引用的場(chǎng)景都能泄漏掉 Activity,從而泄漏 Activity 持有的大量 View 和其他對(duì)象。

?

事實(shí)上,ResourceCanary 將檢測(cè)與分析分離和大幅裁剪了 Hprof 文件體積的改進(jìn)是相當(dāng)重要的,這使我們將 Activity 檢查做成自動(dòng)化變得更容易。我們將 ResourceCanary 的 sdk 植入在微信中,通過(guò)每日常規(guī)的自動(dòng)化測(cè)試,將發(fā)現(xiàn)的問(wèn)題上報(bào)到微信的 Matrix 平臺(tái),自動(dòng)進(jìn)行統(tǒng)計(jì)、棧提取、歸責(zé)、建單,然后系統(tǒng)會(huì)自動(dòng)通知相關(guān)開(kāi)發(fā)同學(xué)進(jìn)行修復(fù),并可以持續(xù)跟進(jìn)修復(fù)情況。對(duì)有效解決問(wèn)題的意義非常大。

?

?

除了開(kāi)發(fā)同學(xué)每天根據(jù) Matrix 平臺(tái)的報(bào)告進(jìn)行確認(rèn)修復(fù)外,對(duì)于這些泄漏,微信客戶端還會(huì)采取一些主動(dòng)措施規(guī)避掉無(wú)法立即解決的泄漏,大致包括:

?

  • 主動(dòng)切斷 Activity 對(duì) View 的引用、回收 View 中的 Drawable,降低 Activity 泄漏帶來(lái)的影響

  • 盡量用 Application Context 獲取某些系統(tǒng)服務(wù)實(shí)例,規(guī)避系統(tǒng)帶來(lái)的內(nèi)存泄漏

  • 對(duì)于已知的無(wú)法通過(guò)上面兩步解決的來(lái)自系統(tǒng)的內(nèi)存泄漏,參考 LeakCanary 給出的建議進(jìn)行規(guī)避

    ?

Bitmap 分配及回收追蹤

Bitmap 一直以來(lái)都是 Android App 的內(nèi)存消耗大戶,很多 Java 甚至 native 內(nèi)存問(wèn)題的背后都是不當(dāng)持有了大量大小很大的 Bitmap。

?

與此同時(shí),Bitmap 有幾個(gè)特點(diǎn)方便我們對(duì)它們進(jìn)行監(jiān)控:

?

  • 創(chuàng)建場(chǎng)景較為單一。?Bitmap 通常通過(guò)在 Java 層調(diào)用?Bitmap.create?直接創(chuàng)建,或者通過(guò)?BitmapFactory?從文件或網(wǎng)絡(luò)流解碼。正好,我們有一層對(duì) Bitmap 創(chuàng)建接口調(diào)用的封裝,基本囊括微信內(nèi)創(chuàng)建 Bitmap 的全部場(chǎng)景(包括調(diào)用外部庫(kù)產(chǎn)生 Bitmap 也封裝在這層接口內(nèi))。這層統(tǒng)一接口有利于我們?cè)趧?chuàng)建 Bitmap 時(shí)進(jìn)行統(tǒng)一監(jiān)控,而不需要進(jìn)行插樁或 hook 等較為 hack 的方法。

  • 創(chuàng)建頻率較低。?Bitmap 創(chuàng)建的行為不如 malloc 等通用內(nèi)存分配頻繁,本身往往也伴隨著耗時(shí)較長(zhǎng)的解碼或處理,因此在創(chuàng)建 Bitmap 時(shí)加入監(jiān)控邏輯,其性能要求不會(huì)特別高。即使是獲取完整的 Java 堆棧甚至做一些篩選,其耗時(shí)相比起解碼或者其他圖像處理也是微不足道,我們可以執(zhí)行稍微復(fù)雜的邏輯。

  • Java 對(duì)象的生命周期。?Bitmap 對(duì)象的生命周期和普通 Java 對(duì)象一樣服從 JVM 的 GC,因此我們可以通過(guò)?WeakReference?等手段來(lái)跟蹤 Bitmap 的銷毀,而不用像創(chuàng)建一樣對(duì)銷毀也一并跟蹤。

?

針對(duì)上述特點(diǎn),我們加入了一個(gè)針對(duì) Bitmap 的高性價(jià)比監(jiān)控:在接口層中將所有被創(chuàng)建出來(lái)的 Bitmap 加入一個(gè)?WeakHashMap,同時(shí)記錄創(chuàng)建 Bitmap 的時(shí)間、堆棧等信息,然后在適當(dāng)?shù)臅r(shí)候查看這個(gè)?WeakHashMap?看看哪些 Bitmap 仍然存活來(lái)判斷是否出現(xiàn) Bitmap 濫用或泄漏。

?

這個(gè)監(jiān)控對(duì)性能消耗非常低,可以在發(fā)布版進(jìn)行。判斷是否泄漏則需要耗費(fèi)一點(diǎn)性能,且目前還需要人工處理。收集泄漏的時(shí)機(jī)包括:

?

  • 如果是測(cè)試環(huán)境,比如 Monkey Test 過(guò)程中,則使用 “激進(jìn)模式”,即每次進(jìn)行 Bitmap 創(chuàng)建的數(shù)秒后都檢查一次 Java 堆的情況,Java 內(nèi)存占用超過(guò)某個(gè)閾值即觸發(fā)收集邏輯,將所有存活的 Bitmap 信息輸出到文件,另外還輸出 hprof 輔助查找別的內(nèi)存泄漏。

  • 發(fā)布版則采用 “保守模式”,只有在出現(xiàn) OOM 了之后,才將內(nèi)存占用 1 MB 以上的 Bitmap 信息輸出到 xlog,避免 xlog 過(guò)大。

?

激進(jìn)模式中閾值目前定為 200 MB,這是因?yàn)槲覀冎С值?Android 設(shè)備中,最容易出現(xiàn) OOM 的一批手機(jī)的 large heap 限制為 256 MB,一旦 Heap 峰值達(dá)到 200 MB 以上且回收不及時(shí),在一些需要類似解碼大圖的場(chǎng)景下就會(huì)出現(xiàn)無(wú)法臨時(shí)分配數(shù)十 MB 的內(nèi)存供圖片顯示而導(dǎo)致 OOM,因此在 Monkey Test 時(shí)認(rèn)為 Java Heap 占用超過(guò) 200 MB 即為異常。

?

Bitmap 追蹤嘗試投入到 Monkey Test 后,發(fā)現(xiàn)問(wèn)題最多最突出的,是緩存的濫用問(wèn)題,最為典型的是使用 static LRUCache 來(lái)緩存大尺寸 Bitmap

?

private?static?LruCache<String,?Bitmap>?sBitmapCache?=?new?LruCache<>(20);public?static?Bitmap?getBitmap(String?path)?{Bitmap?bitmap?=?sBitmapCache.get(path);if?(bitmap?!=?null)?{return?bitmap;}bitmap?=?decodeBitmapFromFile(path);sBitmapCache.put(path,?bitmap);return?bitmap;}

?

比如上面的代碼,作用是緩存一些重復(fù)使用的 Bitmap 避免重復(fù)解碼損失性能,但由于?sBitmapCache?是靜態(tài)的且沒(méi)有清理邏輯,緩存在其中的圖片將永遠(yuǎn)無(wú)法釋放,除非 20 個(gè)的配額用盡或圖片被替換。LruCache?對(duì)緩存對(duì)象的?個(gè)數(shù)?進(jìn)行了限制,但沒(méi)有對(duì)對(duì)象的?總大小?進(jìn)行限制(Java的對(duì)象模型也不支持直接獲取對(duì)象占用內(nèi)存大小),因此如果緩存里面存放了數(shù)個(gè)大圖或者長(zhǎng)圖,將長(zhǎng)期占用大量?jī)?nèi)存。此外,不同業(yè)務(wù)之間不太可能提前考慮緩存可能造成的相互擠壓,進(jìn)一步加劇問(wèn)題。也正因如此我們還開(kāi)始推動(dòng)了內(nèi)部使用統(tǒng)一的緩存管理組件,從整體上,控制使用緩存的策略和數(shù)量。

?

Native 內(nèi)存泄漏檢測(cè)

Native 層內(nèi)存泄漏通常是指各種原因?qū)е碌囊逊峙鋬?nèi)存未得到有效釋放,導(dǎo)致可用內(nèi)存越來(lái)越少直到 crash 的問(wèn)題。由于Native 層沒(méi)有 GC 機(jī)制,內(nèi)存管理行為非常可控,檢測(cè)起來(lái)確實(shí)也簡(jiǎn)單許多——直接攔截內(nèi)存分配和釋放相關(guān)的函數(shù)看一下是否配對(duì)即可。

?

我們首先在單個(gè) so 上嘗試了一些成熟的方案:

?

  • valgrind

App 明顯變得卡頓,檢測(cè)結(jié)果沒(méi)有太大幫助,而且 valgrind 在 Android 上的部署太麻煩了,要在幾百臺(tái)測(cè)試機(jī)器上部署是個(gè)很大的問(wèn)題。

  • asan

跟文檔描述得差不多,檢測(cè)階段開(kāi)銷確實(shí)比 valgrind 少,但是 App 還是變卡了,自動(dòng)化測(cè)試時(shí)容易 ANR。回溯堆棧階段容易 crash。另外我們的一些歷史悠久的 so 按 asan 的要求用 clang 編譯之后可能存在 bug,這點(diǎn)也成為了采用此方案的阻礙。

?

對(duì)上述結(jié)果我們的猜想是這些工具除了本身開(kāi)銷之外,大而全的功能,諸如雙重釋放,地址合法性檢測(cè),越界訪問(wèn)檢測(cè)也增加了運(yùn)行時(shí)開(kāi)銷。按此思路我們又改用系統(tǒng)自帶的 malloc_debug 進(jìn)行檢測(cè),但 malloc_debug 在堆棧回溯階段會(huì)產(chǎn)生一個(gè)必現(xiàn)的 crash,按照網(wǎng)上資料和廠商的反饋的說(shuō)法,應(yīng)該是它依賴 stl 庫(kù)里的 __Unwind 系列函數(shù)需要的數(shù)據(jù)結(jié)構(gòu)在不同的 stl 庫(kù)里定義不同導(dǎo)致的,然而由于一些原因,被檢測(cè)的 so 里有些已經(jīng)不具備換 stl 庫(kù)重編的條件了。這樣的狀況迫使我們自研一套方案解決問(wèn)題。

?

根據(jù)之前的嘗試,實(shí)際上我們需要研發(fā)兩個(gè)方案組合使用。對(duì)于不方便重編的庫(kù),我們采用一個(gè)不需要重編的方案舍棄一些信息以換取對(duì)泄漏的定位能力;對(duì)于易于重編的庫(kù),我們采用一個(gè)不需要 clang 環(huán)境的方案保證能在不引入 bug 的情況下拿到 asan 能拿到的泄漏內(nèi)存分配位置的堆棧信息。當(dāng)然,兩個(gè)方案都要足夠輕,保證不會(huì)產(chǎn)生 ANR 中斷自動(dòng)化測(cè)試過(guò)程。

?

限于篇幅,這里不再展開(kāi)介紹方案原理,只大概說(shuō)明兩個(gè)方案的思路:

?

  • 無(wú)法重編的情況:PLT hook 攔截被測(cè)庫(kù)的內(nèi)存分配函數(shù),重定向到我們自己的實(shí)現(xiàn)后記錄分配的內(nèi)存地址、大小、來(lái)源 so 庫(kù)路徑等信息,定期掃描分配與釋放是否配對(duì),對(duì)于不配對(duì)的分配輸出我們記錄的信息。

  • 可重編的情況:通過(guò) gcc 的 -finstrument-functions 參數(shù)給所有函數(shù)插樁,樁中模擬調(diào)用棧入棧出棧操作;通過(guò) ld 的 --wrap 參數(shù)攔截內(nèi)存分配和釋放函數(shù),重定向到我們自己的實(shí)現(xiàn)后記錄分配的內(nèi)存地址、大小、來(lái)源 so?以及插樁記錄的調(diào)用棧此刻的內(nèi)容,定期掃描分配與釋放是否配對(duì),對(duì)于不配對(duì)的分配輸出我們記錄的信息。

?

實(shí)測(cè)中這兩個(gè)方案為每次內(nèi)存分配帶來(lái)的額外開(kāi)銷小于 10ns,總體開(kāi)銷的變化幾乎可忽略不計(jì)。我們通過(guò)這兩套方案組合除了發(fā)現(xiàn)一個(gè)棘手的新問(wèn)題外,還順便檢測(cè)了使用多年的基礎(chǔ)網(wǎng)絡(luò)協(xié)議 so 庫(kù),并成功找出隱藏多年的十多處小內(nèi)存泄漏點(diǎn),降低內(nèi)存地址的碎片化

?

線程監(jiān)控

常見(jiàn)的 OOM 情況大多數(shù)是因?yàn)閮?nèi)存泄漏或申請(qǐng)大量?jī)?nèi)存造成的,比較少見(jiàn)的有下面這種跟線程相關(guān)情況,但在我們 crash 系統(tǒng)上有時(shí)能發(fā)現(xiàn)一些這樣的問(wèn)題。

?

java.lang.OutOfMemoryError:?pthread_create?(1040KB?stack)?failed:?Out?of?memory

?

原因分析

OutOfMemoryError 這種異常根本原因在于申請(qǐng)不到足夠的內(nèi)存造成的,直接的原因是在創(chuàng)建線程時(shí)初始 stack size 的時(shí)候,分配不到內(nèi)存導(dǎo)致的。這個(gè)異常是在 /art/runtime/thread.cc 中線程初始化的時(shí)候 throw 出來(lái)的。

?

void?Thread::CreateNativeThread(JNIEnv*?env,?jobject?java_peer,?size_t?stack_size,?bool?is_daemon)?{...int?pthread_create_result?=?pthread_create(&new_pthread,?&attr,?Thread::CreateCallback,?child_thread);if?(pthread_create_result?!=?0)?{env->SetLongField(java_peer,?WellKnownClasses::java_lang_Thread_nativePeer,?0);{std::string?msg(StringPrintf("pthread_create?(%s?stack)?failed:?%s",PrettySize(stack_size).c_str(),?strerror(pthread_create_result)));ScopedObjectAccess?soa(env);soa.Self()->ThrowOutOfMemoryError(msg.c_str());}}}

?

調(diào)用這個(gè) pthread_create 的方法去 clone 一個(gè)線程,如果返回 pthread_create_result 不為 0,則代表初始化失敗。什么情況下會(huì)初始化失敗,pthread_create 的具體邏輯是在 /bionic/libc/bionic/pthread_create.cpp 中完成:

?

int?pthread_create(pthread_t*?thread_out,?pthread_attr_t?const*?attr,void*?(*start_routine)(void*),?void*?arg)?{...pthread_internal_t*?thread?=?NULL;void*?child_stack?=?NULL;int?result?=?__allocate_thread(&thread_attr,?&thread,?&child_stack);if?(result?!=?0)?{return?result;}...}static?int?__allocate_thread(pthread_attr_t*?attr,?pthread_internal_t**?threadp,?void**?child_stack)?{size_t?mmap_size;uint8_t*?stack_top;...attr->stack_base?=?__create_thread_mapped_space(mmap_size,?attr->guard_size);if?(attr->stack_base?==?NULL)?{return?EAGAIN;?//?EAGAIN?!=?0}...return?0;}

?

可以看到每個(gè)線程初始化都需要 mmap 一定的 stack size,在默認(rèn)的情況下一般初始化一個(gè)線程需要 mmap 1M 左右的內(nèi)存空間,在 32bit 的應(yīng)用中有 4g 的 vmsize,實(shí)際能使用的有 3g+,按這種估算,一個(gè)進(jìn)程最大能創(chuàng)建的線程數(shù)可達(dá) 3000+,當(dāng)然這是理想的情況,在 linux 中對(duì)每個(gè)進(jìn)程可創(chuàng)建的線程數(shù)也有一定的限制(/proc/pid/limits)而實(shí)際測(cè)試中,我們也發(fā)現(xiàn)不同廠商對(duì)這個(gè)限制也有所不同,而且當(dāng)超過(guò)系統(tǒng)進(jìn)程線程數(shù)限制時(shí),同樣會(huì)拋出這個(gè)類型的 OOM。

可見(jiàn)對(duì)線程數(shù)量的限制,可以一定程度避免 OOM 的發(fā)生。所以我們也開(kāi)始對(duì)微信的線程數(shù)進(jìn)行了監(jiān)控統(tǒng)計(jì)。

?

監(jiān)控上報(bào)

我們?cè)诨叶劝姹局型ㄟ^(guò)一個(gè)定時(shí)器 10 分鐘 dump 出應(yīng)用所有的線程,當(dāng)線程數(shù)超過(guò)一定閾值時(shí),將當(dāng)前的線程上報(bào)并預(yù)警,通過(guò)對(duì)這種異常情況的捕捉,我們發(fā)現(xiàn)微信在某些特殊場(chǎng)景下,確實(shí)存在線程泄漏以及短時(shí)間內(nèi)線程暴增,導(dǎo)致線程數(shù)過(guò)大(500+)的情況,這種情況下再創(chuàng)建線程往往容易出現(xiàn) OOM。

在定位并解決這幾個(gè)問(wèn)題后,我們的 crash 系統(tǒng)和廠商的反饋中這種類型 OOM 確實(shí)降低了不少。所以監(jiān)控線程數(shù),收斂線程也成為我們降低 OOM 的有效手段之一。

?

內(nèi)存監(jiān)控

Android 系統(tǒng)中,需要關(guān)注兩類內(nèi)存的使用情況,物理內(nèi)存和虛擬內(nèi)存。通常我們使用 Memory Profiler 的方式查看 APP 的內(nèi)存使用情況。

?

? ? ? ??

在默認(rèn)視圖中,我們可以查看進(jìn)程總內(nèi)存占用、JavaHeap、NativeHeap,以及 Graphics、Stack、Code 等細(xì)分類型的內(nèi)存分配情況。當(dāng)系統(tǒng)內(nèi)存不足時(shí),會(huì)觸發(fā) onLowMemory。在 API Level 14及以上,則有更細(xì)分的 onTrimMemory。實(shí)際測(cè)試中,我們發(fā)現(xiàn) onTrimMemory 的 ComponentCallbacks2.TRIM_MEMORY_COMPLETE 并不等價(jià)于 onLowMemory,因此推薦仍然要監(jiān)聽(tīng) onLowMemory 回調(diào)。

?

除了舊有的大盤粗粒度內(nèi)存上報(bào),我們正在建設(shè)相對(duì)精細(xì)的內(nèi)存使用情況監(jiān)控并集成到 Matrix 平臺(tái)上。進(jìn)行監(jiān)控方案前,我們需要運(yùn)行時(shí)獲得各項(xiàng)內(nèi)存使用數(shù)據(jù)的能力。通過(guò) ActivityManager 的 getProcessMemoryInfo,我們獲得微信進(jìn)程的 Debug.MemoryInfo 數(shù)據(jù)(注意:這個(gè)接口在低端機(jī)型中可能耗時(shí)較久,不能在主線程中調(diào)用,且監(jiān)控調(diào)用耗時(shí),在耗時(shí)過(guò)大的機(jī)型上,屏蔽內(nèi)存監(jiān)控模塊)。通過(guò) hook Debug.MemoryInfo 的 getMemoryStat 方法(需要 23 版本及以上),我們可以獲得等價(jià)于 Memory Profiler 默認(rèn)視圖中的多項(xiàng)數(shù)據(jù),從而獲得細(xì)分內(nèi)存使用情況。此外,通過(guò) Runtime 可獲得 DalvikHeap;通過(guò) Debug.getNativeHeapAllocatedSize 可獲得 NativeHeap。至此,我們可以獲得低內(nèi)存發(fā)生時(shí),微信的虛擬內(nèi)存、物理內(nèi)存的各項(xiàng)數(shù)據(jù),從而實(shí)現(xiàn)監(jiān)控。

?

內(nèi)存監(jiān)控將分為常規(guī)監(jiān)控和低內(nèi)存監(jiān)控兩個(gè)場(chǎng)景。

?

  • 常規(guī)內(nèi)存監(jiān)控 —— 微信使用過(guò)程中,內(nèi)存監(jiān)控模塊會(huì)根據(jù)斐波那契數(shù)列的特性,每隔一段時(shí)間(最長(zhǎng)30分鐘)獲取內(nèi)存的使用情況,從而獲得微信隨使用時(shí)間而變化的內(nèi)存曲線。

  • 低內(nèi)存監(jiān)控 —— 通過(guò) onLowMemory 的回調(diào),或者通過(guò) onTrimMemory 回調(diào)且不同的標(biāo)記位,結(jié)合 ActivityManager.MemoryInfo 的 lowMemory 標(biāo)記,我們可以獲得低內(nèi)存的發(fā)生時(shí)機(jī)。這里需要注意,只有物理內(nèi)存不足時(shí),才會(huì)引起 onLowMemory 回調(diào)。超過(guò)虛擬內(nèi)存的大小限制則直接觸發(fā) OOM 異常。因此我們也監(jiān)聽(tīng)虛擬內(nèi)存的占用情況,當(dāng)虛擬內(nèi)存占用超過(guò)最大限制的 90% 時(shí),觸發(fā)為低內(nèi)存告警。低內(nèi)存監(jiān)控將監(jiān)控低內(nèi)存的發(fā)生頻率、發(fā)生時(shí)各項(xiàng)內(nèi)存使用情況監(jiān)控、發(fā)生時(shí)微信的當(dāng)前場(chǎng)景等。

?

兜底保護(hù)

除了上面的各種問(wèn)題及解決手段外,面對(duì)各種未知的、難以及時(shí)發(fā)現(xiàn)問(wèn)題,目前我們也提出了一個(gè)兜底保護(hù)策略進(jìn)行嘗試。

?

從大盤統(tǒng)計(jì)的數(shù)據(jù)上看,我們發(fā)現(xiàn)微信主進(jìn)程存活的時(shí)間超過(guò)一天的用戶達(dá)千萬(wàn)級(jí)別,占比 1.5%+,倘若應(yīng)用本身或系統(tǒng)底層存在細(xì)微的內(nèi)存泄漏,短時(shí)間上不會(huì)造成 OOM,但在長(zhǎng)時(shí)間的使用中,會(huì)使得應(yīng)用占用內(nèi)存越積越大,最終也會(huì)造成 OOM 情況發(fā)生。在這種情況下,我們也在思考,如果可以提前知道內(nèi)存的占用情況,以及用戶當(dāng)前的使用場(chǎng)景,那么我們可以將這種異常的情況進(jìn)行兜底保護(hù),來(lái)避免不可控的且容易讓用戶感知到的 OOM 現(xiàn)象。

?

?

如何兜底

OOM 會(huì)使得進(jìn)程被殺,實(shí)際上也是系統(tǒng)處理異常所拋出來(lái)的信號(hào)及處理方式。如果應(yīng)用本身也充當(dāng)起這個(gè)角色,相比系統(tǒng)而言,我們可以根據(jù)具體場(chǎng)景,更加靈活的提前處理這種異常情況。其中最大的好處在于,可以在用戶無(wú)感知的情況下,在接近觸發(fā)系統(tǒng)異常前,選擇合適的場(chǎng)景殺死進(jìn)程并將其重啟,使得應(yīng)用的內(nèi)存占用回到正常情況,這不為是一種好的兜底方式。

這里我們主要考慮了幾種條件:

?

  • 微信是否在主界面退到后臺(tái) 且 位于后臺(tái)的時(shí)間超過(guò) 30 分鐘

  • 當(dāng)前時(shí)間為凌晨 2~5 點(diǎn)

  • 不存在前臺(tái)服務(wù)(存在通知欄,音樂(lè)播放欄等情況)

  • java heap 必須大于當(dāng)前進(jìn)程最大可分配的 85% || native 內(nèi)存大于 800M || vmsize 超過(guò)了 4G(微信 32bit)的 85%

  • 非大量的流量消耗(每分鐘不超過(guò) 1M) && 進(jìn)程無(wú)大量 CPU 調(diào)度情況?

?

在滿足以上幾種條件下,殺死當(dāng)前微信主進(jìn)程并通過(guò) push 進(jìn)程重新拉起及初始化,來(lái)進(jìn)行兜底保護(hù)。在用戶角度,當(dāng)用戶將微信切回前臺(tái)時(shí),不會(huì)看到初始化界面,還是位于主界面中,所以也不會(huì)感到突兀。從本地測(cè)試及灰度的結(jié)果上看,應(yīng)用上該兜底策略,可以有效的減少用戶出現(xiàn) OOM 的情況,在灰度的 5w 用戶中,有 3、4 個(gè)是命中了這個(gè)兜底策略,但具體兜底的策略是否合理,還需要經(jīng)過(guò)更嚴(yán)格的測(cè)試才能確認(rèn)上線。

?

總結(jié)

通過(guò)上面的文章,我們盡可能多的介紹了多個(gè)方面的內(nèi)存問(wèn)題優(yōu)化手段和工程實(shí)踐。因?yàn)槠邢?#xff0c;一些不那么顯著的問(wèn)題和不少細(xì)節(jié)無(wú)法詳細(xì)展開(kāi)。總的來(lái)說(shuō),我們優(yōu)化實(shí)踐的思路是在研發(fā)階段不斷實(shí)現(xiàn)更多的工具和組件,系統(tǒng)性的并逐步提升自動(dòng)化程度從而提升發(fā)現(xiàn)問(wèn)題的效率。

?

當(dāng)然不得不提的是,即使做了這么多努力,內(nèi)存問(wèn)題仍沒(méi)有徹底消滅,仍有問(wèn)題會(huì)因?yàn)槿鄙傩畔⒍y以定位原因、或因?yàn)闇y(cè)試路徑無(wú)法覆蓋而無(wú)法提前發(fā)現(xiàn),還有兼容性的問(wèn)題、引入的外部組件有泄漏等等,以及我們還需要更多的系統(tǒng)化和自動(dòng)化,這是我們還在不斷優(yōu)化和改進(jìn)的方向。

?

希望已有的這些經(jīng)驗(yàn)?zāi)軐?duì)大家有所幫助,優(yōu)化沒(méi)有盡頭。

現(xiàn)在加Android高級(jí)開(kāi)發(fā)群;701740775,可免費(fèi)領(lǐng)取一份最新Android高級(jí)架構(gòu)技術(shù)體系大綱和進(jìn)階視頻資料,以及這些年年積累整理的所有面試資源筆記。加群請(qǐng)備注csdn領(lǐng)取xx資料

總結(jié)

以上是生活随笔為你收集整理的微信 Android 终端内存优化实践的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

久爱精品在线 | 中文免费观看 | 蜜桃麻豆www久久囤产精品 | 午夜视频久久久 | 蜜臀久久99精品久久久无需会员 | 性色视频在线 | 三上悠亚一区二区在线观看 | 国产精品一区二区av日韩在线 | 五月激情婷婷丁香 | 久久久久久久久久久免费 | 天天干天天玩天天操 | 欧美伦理一区二区三区 | 色中射| 96看片 | 欧洲高潮三级做爰 | 欧美色综合天天久久综合精品 | 国产淫片免费看 | 美女网站黄在线观看 | www.97视频| 在线 日韩 av | 日本最新高清不卡中文字幕 | 亚洲精品国产自产拍在线观看 | 91成人精品在线 | 奇米网网址 | 夜夜躁天天躁很躁波 | 久草在线资源观看 | 欧美日韩久 | 91精品办公室少妇高潮对白 | 国产精品乱码久久久 | www.婷婷色| 日韩在线 一区二区 | 激情开心网站 | 久久蜜臀av | av成人在线播放 | 亚洲一区视频在线播放 | 国产天天综合 | 亚洲黄色片一级 | 亚洲日本欧美在线 | 午夜性色| 亚洲另类视频在线 | 免费在线播放av电影 | 欧美激情h | www五月天婷婷 | 亚洲mv大片欧洲mv大片免费 | 国产一级二级视频 | 中文字幕在线观看第一页 | 国产精品黄色在线观看 | 少妇bbbb揉bbbb日本 | 在线观看中文字幕视频 | 日韩视频免费观看高清 | 99热精品国产一区二区在线观看 | 美女国内精品自产拍在线播放 | 日本三级久久久 | 亚洲综合色播 | 夜夜骑日日操 | 亚洲成年片 | 99视频在线精品国自产拍免费观看 | 成年人视频免费在线播放 | 成年人视频在线观看免费 | 久久a视频 | 成人av免费电影 | 毛片网站在线 | 91麻豆高清视频 | 免费观看性生活大片 | 粉嫩一区二区三区粉嫩91 | 欧美精品被 | 日韩视频在线观看视频 | 国产一级大片免费看 | 91精品啪在线观看国产81旧版 | 97网| 久久av中文字幕片 | 91在线播放视频 | 久久在线免费观看 | 日韩成人精品 | 国产美女搞久久 | 免费国产黄线在线观看视频 | 日韩欧美高清不卡 | 视频在线国产 | 五月婷婷综合网 | 国产一区二区手机在线观看 | 日韩精品观看 | 国产精品国产毛片 | 国产精品24小时在线观看 | 国产精品久久久久久一区二区 | 一区二区三区免费在线观看视频 | 国产免费成人 | 96av视频| 在线免费黄色毛片 | 美女黄频在线观看 | 国产精品九九热 | 亚洲区精品视频 | 久久久久国产精品www | 黄色免费视频在线观看 | 最新精品视频在线 | 婷婷激情站| 成人动态视频 | 91精品久久久久久粉嫩 | 国产精品av一区二区 | 欧美a性| 国产亚洲综合性久久久影院 | 欧美福利精品 | 国产在线观看h | 国产精品入口麻豆www | 九九免费精品 | 精品欧美乱码久久久久久 | 精品国产成人av在线免 | 一区二区不卡视频在线观看 | 久久精品国产一区二区电影 | 天天操天天干天天综合网 | 国产a高清| 国产成人精品综合久久久久99 | 一区二区中文字幕在线播放 | 九九热久久免费视频 | 中文字幕a∨在线乱码免费看 | 狠狠操操操| 不卡的av在线播放 | 精品一区免费 | 欧美在线视频一区二区三区 | 久久久久国产一区二区 | 国产精品人人做人人爽人人添 | 久久夜色精品亚洲噜噜国4 午夜视频在线观看欧美 | www99久久| 久久视频国产精品免费视频在线 | 亚洲专区视频在线观看 | 国产精品电影一区二区 | 91污视频在线观看 | 国产免费不卡 | 精品一区在线 | 精品一二三四在线 | 天天色综合三 | 一区二区三区不卡在线 | 日本护士三级少妇三级999 | 密桃av在线| 精品一区免费 | 最近中文字幕免费 | 国产精品永久免费观看 | 69久久99精品久久久久婷婷 | 亚洲天堂精品视频在线观看 | 公与妇乱理三级xxx 在线观看视频在线观看 | 久久高视频 | 婷婷五月在线视频 | 91麻豆精品国产91久久久无需广告 | 97超碰在线免费观看 | 激情av网址| 日本黄色片一区二区 | 精品视频国产一区 | 亚洲欧美日韩国产一区二区三区 | 69av视频在线| 午夜精品婷婷 | 欧美片网站yy | 国产一区成人在线 | 成人av免费在线 | 欧美国产91 | 二区三区在线视频 | 国产中文字幕在线视频 | 亚洲中字幕 | 奇米777777 | 日韩乱理 | 国产精品免费在线 | 日韩免费视频观看 | 黄色免费视频在线观看 | 男女全黄一级一级高潮免费看 | 高清精品视频 | 国产做a爱一级久久 | 欧美精品三级 | 日韩电影中文,亚洲精品乱码 | 国产精品对白一区二区三区 | 久久免费视频5 | 黄免费在线观看 | 中文字幕亚洲五码 | 国产成人精品久 | 热九九精品 | 麻豆观看| 91在线区| 中文字幕乱在线伦视频中文字幕乱码在线 | 91亚色视频 | 欧美一级片在线播放 | www日韩在线 | 午夜 在线| 99超碰在线观看 | 天天爽天天爽天天爽 | 欧美二区视频 | 国产高清视频免费观看 | 国产中文字幕视频在线观看 | 人交video另类hd| 久久香蕉国产 | 色资源网在线观看 | 免费看一及片 | 国产精品一区二区在线播放 | 福利在线看片 | 成人性生交大片免费看中文网站 | 国产精品第54页 | 日本三级在线观看中文字 | 精品在线观 | 亚州视频在线 | 成人精品久久久 | 日韩中文在线字幕 | 久久在线视频精品 | 精品国产中文字幕 | 香蕉在线观看视频 | 婷婷国产一区二区三区 | 国产成人免费观看久久久 | 黄色字幕网 | 夜夜躁日日躁 | 一本色道久久综合亚洲二区三区 | 免费观看性生活大片 | www婷婷| 黄色在线观看免费网站 | av在线之家电影网站 | 久久九九久久九九 | 在线观看亚洲免费视频 | 日韩av片在线 | 美女视频永久黄网站免费观看国产 | 91视频啊啊啊 | 日韩视频图片 | 欧美激情va永久在线播放 | 手机在线日韩视频 | 国产专区在线看 | 精品久久久久久亚洲综合网 | www日日夜夜 | 天天操操| 国产日韩精品在线观看 | 免费毛片一区二区三区久久久 | 国产婷婷视频在线 | 亚州中文av | 久草视频中文 | 久久九九影院 | 精品美女久久久久 | 欧美一区在线观看视频 | 九九视频一区 | 亚洲一区黄色 | 色鬼综合网 | 综合网伊人 | 欧美色噜噜 | 欧美国产高清 | 天天天干天天射天天天操 | 激情网婷婷 | 国产a精品 | 久久这里只有精品23 | 久久97超碰 | 国产成人精品久久久久蜜臀 | 国产精品久久久久毛片大屁完整版 | 在线免费观看一区二区三区 | 精品麻豆| 激情网五月婷婷 | 免费男女羞羞的视频网站中文字幕 | 黄www在线观看 | 黄色软件在线观看视频 | 亚洲va欧美va人人爽春色影视 | 天天插日日操 | 中文字幕第一页在线播放 | 99久久99久久精品国产片 | 99精品视频网站 | 97精品久久 | 97精品伊人 | a级片韩国 | 日韩精品三区四区 | 午夜美女网站 | 五月天丁香亚洲 | 国产精品永久久久久久久www | 蜜臀av性久久久久蜜臀av | 国产伦精品一区二区三区高清 | 天天曰天天 | 成人午夜网址 | 久草在线视频网 | 国产最新精品视频 | 日韩一二区在线 | 欧美在线观看禁18 | 在线观av | 久久久久亚洲天堂 | 97人人添人澡人人爽超碰动图 | 婷婷av色综合 | 久久99国产精品久久 | 欧美另类sm图片 | 91成人区 | 久草免费在线观看视频 | 操久久免费视频 | 91福利在线导航 | 精品国自产在线观看 | 久久综合丁香 | 亚洲精品 在线视频 | 国产一区二区三精品久久久无广告 | 国产亚洲欧美一区 | 久草网站在线 | 精品999在线观看 | 久久 国产一区 | 国产在线高清精品 | 天天操天天色天天射 | 91av久久 | 久草99| 成人 亚洲 欧美 | 天天爱天天操天天射 | 日本三级全黄少妇三2023 | 一级片免费观看视频 | 精品国产久 | 日韩免费高清 | 久久久久国产精品午夜一区 | 2020天天干天天操 | 国产精品欧美久久久久无广告 | 在线观看久久 | 性色av免费看 | 天天干天天做天天爱 | 日韩二区在线观看 | 又色又爽的网站 | 欧美了一区在线观看 | www.夜夜操 | 丁香六月综合网 | 91亚·色 | 97视频在线观看播放 | 国产美女网站在线观看 | 亚洲色图美腿丝袜 | 狠狠色婷婷丁香六月 | 免费黄色在线网址 | 国内成人精品视频 | 欧美日韩伦理一区 | 国产亚洲精品久久久久5区 成人h电影在线观看 | 97超级碰碰碰碰久久久久 | 久久久久久欧美二区电影网 | 国产美女网站在线观看 | 日韩一级黄色av | 99久久www | 国产精品成人aaaaa网站 | 国产精品福利一区 | 永久av免费在线观看 | 日韩久久精品一区二区三区 | 日韩免费网站 | 中文字幕永久免费 | 欧美极品少妇xxxxⅹ欧美极品少妇xxxx亚洲精品 | 国产精品国产自产拍高清av | 久久久在线视频 | 高清免费在线视频 | 国产最新精品视频 | 亚洲综合成人专区片 | 天堂久久电影网 | 91尤物在线播放 | 国产自制av| 99热亚洲精品 | 日韩网页 | 伊人影院得得 | av蜜桃在线 | 中文字幕欧美日韩va免费视频 | 日本中文在线观看 | 在线国产能看的 | av千婊在线免费观看 | 亚洲精品影视 | av线上看| 久草在线视频首页 | 最近高清中文字幕 | 中文字幕有码在线播放 | 天天综合天天做天天综合 | 91一区一区三区 | 日韩特黄一级欧美毛片特黄 | 日韩网站在线 | 97精品国产手机 | 人人舔人人插 | 日韩欧美视频 | 日韩av在线网站 | 国产高清在线永久 | 日产乱码一二三区别免费 | 欧美一级在线 | 亚洲国产视频直播 | av成人免费在线 | 91麻豆精品久久久久久 | 久在线 | 国产精品ⅴa有声小说 | 中文字幕在线观看亚洲 | 免费合欢视频成人app | 亚洲另类久久 | 亚洲精品在线观看视频 | 国产成人777777 | www一起操| 麻豆免费在线视频 | 久久免费视频5 | 人人插人人艹 | 啪嗒啪嗒免费观看完整版 | 久久视频在线免费观看 | 91高清完整版在线观看 | a黄在线观看 | 国产一级片免费观看 | av不卡中文字幕 | 亚洲va欧美va人人爽 | 国产黄色在线观看 | 国产专区在线视频 | 日韩欧美电影在线观看 | 日韩在线视频一区二区三区 | 91精品在线看| 成人在线视频一区 | 激情五月六月婷婷 | 91大神在线观看视频 | 久久久久久久久久久久久影院 | 国产精品视频最多的网站 | 成人黄色在线电影 | 中文字幕一区二 | 波多野结衣视频一区 | 91精品国 | 91.dizhi永久地址最新 | 久久99精品一区二区三区三区 | 欧美成人高清 | 色姑娘综合| 五月婷婷中文网 | 中文字幕第一页av | 国产精品情侣视频 | 欧美一区在线看 | 久久在线免费观看 | 国产不卡视频在线 | 日韩欧美高清不卡 | 免费观看一级成人毛片 | 日本久久久久久 | 久久精品视频一 | 午夜性生活 | 成人av观看 | 激情狠狠干 | 亚洲天堂视频在线 | 国产视频精品视频 | av看片网| 国产激情小视频在线观看 | 黄a在线观看 | 亚洲专区欧美专区 | 久久性生活片 | 亚洲精品456在线播放第一页 | 国产精品久久久久一区二区三区 | 伊人五月婷 | 成人h视频 | 91麻豆精品国产91久久久更新时间 | 97色综合 | 91最新在线 | 久久精品中文字幕 | 色丁香综合 | 久久99视频精品 | 亚洲3级 | 亚洲一区二区精品3399 | 免费成人在线观看视频 | 99精品在线观看 | 91精品国自产在线偷拍蜜桃 | 91av片| 国产成人久久久77777 | 久久伊人综合 | 欧美最猛性xxxx | 91精品啪 | www.久久色| 亚洲欧美va| 国产高清亚洲 | 一级理论片在线观看 | 99久久精品免费 | 亚洲aⅴ一区二区三区 | 91在线文字幕 | 免费激情网 | 色婷婷一 | 99综合电影在线视频 | 国产在线91在线电影 | 国产精品毛片一区视频播不卡 | 精品久久久久久亚洲综合网站 | av在线a| 日韩欧美在线视频一区二区三区 | 国产黄色成人av | 欧美小视频在线观看 | 午夜手机电影 | 999成人| 欧洲精品码一区二区三区免费看 | 亚洲视频在线观看免费 | 国产在线观看你懂得 | 久久免费在线视频 | 久久精品99| 97超碰在线资源 | 精品在线小视频 | 国产一级二级av | av电影一区 | 日韩毛片在线一区二区毛片 | 中文字幕在线观看完整版电影 | 久久深夜福利免费观看 | 日韩动漫免费观看高清完整版在线观看 | 国产精品久久久久久久久久久久午 | 成人av影院在线观看 | 日本中文字幕在线一区 | 99久久精品无免国产免费 | 精品视频成人 | 五月婷婷综合激情 | 国产色啪| 国产精品久久久久国产a级 激情综合中文娱乐网 | 国产黄大片 | 日韩特级片 | 免费在线色电影 | 国产精品免费在线播放 | 成人在线观看影院 | 中文字幕的 | 日韩精品免费一区二区 | 国产一区二区播放 | 在线观看日韩av | 色婷婷亚洲婷婷 | 伊人激情网| 国产一区二区三区免费在线 | 日韩综合第一页 | 国产精品久久久久久久久久妇女 | 久久人人爽人人人人片 | 91成人在线视频观看 | 色综合天天综合在线视频 | 在线观看中文字幕亚洲 | 亚洲视频综合在线 | 日日日日干| 97免费视频在线 | 久久综合九色综合久久久精品综合 | 天天插天天操天天干 | 97成人免费视频 | 精品久久一区二区 | 久久99精品久久久久久三级 | 99久久婷婷国产精品综合 | 色婷五月| 婷婷国产一区二区三区 | 国产专区在线视频 | 美女网站视频免费黄 | 中文国产成人精品久久一 | 狠狠色婷婷丁香六月 | 国产精品久久久久久婷婷天堂 | 日韩中文字幕免费视频 | 五月天久久综合 | 在线a亚洲视频播放在线观看 | 日韩69视频 | 69xx视频 | 亚洲高清在线观看视频 | 免费视频久久久久久久 | 国产91粉嫩白浆在线观看 | 日韩在线视 | 欧美乱码精品一区二区 | 亚洲国产精品成人综合 | 中文在线最新版天堂 | 最近中文字幕mv | 久草在线视频网站 | 91在线视频免费 | 久久精品国亚洲 | 亚洲精品国产精品国产 | 国产精品久久久久久妇 | 波多野结衣在线播放一区 | 免费观看一级成人毛片 | 999在线精品 | 99国产在线观看 | 精品国产一区二 | 麻豆91视频| 天天做夜夜做 | 深爱激情五月综合 | 99久久夜色精品国产亚洲 | 97国产电影 | 久久 精品一区 | 免费在线激情电影 | 国产精品久久久亚洲 | 一本一本久久a久久精品综合 | 黄色亚洲免费 | 亚洲 中文 在线 精品 | 久久黄色免费视频 | 91在线看视频免费 | 久久久久久久久久久久亚洲 | 在线视频观看成人 | www色,com| 欧美精彩视频在线观看 | 日日综合网 | 婷婷丁香社区 | 国产精品毛片一区二区在线 | 超碰97人| 在线观看中文 | 欧美va天堂va视频va在线 | av资源在线看 | 日日麻批40分钟视频免费观看 | 欧美一区二区在线免费观看 | 久久婷婷丁香 | av网站在线免费观看 | 国产一区在线播放 | 久久色视频 | 高清av中文在线字幕观看1 | 中文字幕 在线看 | 国产玖玖精品视频 | 国产精品2020 | 亚洲成人黄 | 91视频在线免费下载 | 免费看一级一片 | 五月天婷婷狠狠 | 美腿丝袜一区二区三区 | 成人影视免费看 | 国产中文字幕在线观看 | 人人超碰人人 | 激情丁香久久 | 久久在线视频在线 | 91色在线观看 | 岛国av在线免费 | 97免费中文视频在线观看 | 91成人区 | 亚洲精品网页 | 日韩精品视频一二三 | 国产理论一区二区三区 | 69视频网站| 精品你懂的| 在线免费观看涩涩 | 999超碰 | 色爱区综合激月婷婷 | 人人射人人爽 | 草久中文字幕 | 少妇性aaaaaaaaa视频 | 伊人影院在线观看 | 欧美久久99 | 男女激情网址 | 国产成人在线观看免费 | 欧美精品国产综合久久 | 天天射天天搞 | 天天色天天射天天操 | 婷婷丁香av | 亚洲精品tv久久久久久久久久 | 亚洲免费一级 | 欧美日韩后 | 国产成人精品一区一区一区 | 在线观看日韩一区 | 五月天综合激情网 | 日韩视频中文 | 国产在线观看不卡 | 国产精品一区二区三区四区在线观看 | 808电影| av资源在线看 | 夜夜狠狠 | 亚洲天天在线 | 久久人人爽 | 激情网第四色 | 日韩精品欧美视频 | 欧美日韩亚洲精品在线 | 久久无码av一区二区三区电影网 | 成年人免费在线观看网站 | 久久资源总站 | www国产亚洲精品 | 中文字幕在线播放一区 | 欧美日韩精品网站 | 五月婷婷色 | 国产成人99久久亚洲综合精品 | 91精品国产综合久久久久久久 | 欧洲一区精品 | 国产高清视频在线观看 | 成人黄色片免费看 | 欧美福利精品 | 成人免费视频观看 | 国产黄色看片 | 香蕉精品在线观看 | 国产精品久久久久久久久久久杏吧 | 91国内在线| 又黄又爽又无遮挡的视频 | 少妇性色午夜淫片aaaze | 黄在线 | 最新国产精品亚洲 | 久久视频免费观看 | 久久99精品一区二区三区三区 | 97夜夜澡人人双人人人喊 | 综合久久婷婷 | 综合激情 | 国产一级视频在线 | 深夜国产福利 | 久久精品99国产 | 欧美精品视 | 亚洲精品玖玖玖av在线看 | 成人在线观看资源 | 嫩草91影院 | 99国内精品久久久久久久 | 午夜精品一区二区三区在线视频 | 成年人av在线播放 | 久久精品一二三 | 久草影视在线 | 亚洲最大成人免费网站 | 成人av免费 | 人人爽人人片 | 国产精品第一页在线观看 | 久久毛片网站 | 久久精品人 | 丁香六月婷 | 西西www4444大胆在线 | 色av男人的天堂免费在线 | 中中文字幕av | 天天艹天天 | 国产偷v国产偷∨精品视频 在线草 | 成人午夜精品久久久久久久3d | 911香蕉| 蜜臀久久99精品久久久久久网站 | 亚洲综合婷婷 | 97夜夜澡人人爽人人免费 | 日韩激情视频在线观看 | 国产 在线 日韩 | 欧美日韩久久 | 狠狠色丁香久久综合网 | 国产精品一区二区三区免费看 | 久久在线 | 毛片视频电影 | 免费影视大全推荐 | 亚洲免费av电影 | 久久久国产精品网站 | av黄色影院 | 国产高清av免费在线观看 | 成人在线观看免费 | 日韩av专区 | 久久综合中文色婷婷 | 久久爱992xxoo| 亚洲精选视频在线 | 国产一线二线三线在线观看 | 国产在线小视频 | 国产精品女同一区二区三区久久夜 | 日韩欧美亚州 | 精品久久国产一区 | 亚洲精品国产日韩 | 五月天天在线 | 亚洲精品国久久99热 | 在线播放日韩av | 国产不卡精品 | 日韩网站免费观看 | 中文字幕永久在线 | 欧美精品久久久久久久亚洲调教 | 91精品国产91热久久久做人人 | 日日夜夜干 | av中文字幕日韩 | 91精彩视频 | 国产一区欧美在线 | 91天天操 | 日韩精品一区二区在线观看 | 中文字幕在线看视频 | 久久久影片 | 免费男女羞羞的视频网站中文字幕 | 国产一级特黄电影 | 国产精品毛片久久久 | 免费网址你懂的 | 欧美91精品久久久久国产性生爱 | www.五月婷婷 | 国产黄色一级片在线 | 91夜夜夜 | 婷婷久久婷婷 | 亚洲干| 最新婷婷色 | 亚洲成人精品影院 | 夜夜看av | 日韩av片无码一区二区不卡电影 | 成人午夜电影免费在线观看 | 亚洲乱亚洲乱亚洲 | 中文字幕4 | 美女免费av| 在线观看mv的中文字幕网站 | 99精品视频免费观看视频 | 黄色免费观看网址 | 国产高清在线a视频大全 | 91在线视频观看免费 | 9在线观看免费高清完整版 玖玖爱免费视频 | 欧美99热 | 99热国内精品| 亚洲高清在线观看视频 | 一区二区三区国产精品 | 天天射天天干天天操 | 国产精品成人aaaaa网站 | 九九色在线观看 | 欧美日韩高清一区二区 | 免费福利在线播放 | 久久这里 | 国产免费av一区二区三区 | 国产97免费 | 久久精品综合一区 | 中文字幕一区二区三区在线观看 | 国产精品成人自产拍在线观看 | 在线色资源 | 黄色软件视频大全免费下载 | 日韩电影中文字幕在线观看 | 亚洲人成网站精品片在线观看 | 狠狠干夜夜 | 国产伦理一区 | 免费精品在线视频 | 久久成人免费 | a在线视频v视频 | 激情综合六月 | 欧美日韩国产一区二区三区在线观看 | 色老板在线| 日韩亚洲精品电影 | 色婷婷综合久久久久中文字幕1 | 久久久久久久久综合 | 全久久久久久久久久久电影 | 亚洲精品视频在线播放 | 成人全视频免费观看在线看 | 欧美日韩国产精品久久 | 一级全黄毛片 | 久久福利精品 | 天天躁日日躁狠狠躁av中文 | 玖玖玖在线观看 | 中文av在线播放 | 中国一级片在线观看 | 美女久久久 | 久久久999免费视频 日韩网站在线 | 国产一区二区三区高清播放 | 亚洲色图22p | 美女网站色 | 亚洲精品一区中文字幕乱码 | 丁香六月婷婷开心婷婷网 | 午夜精品久久久久久久久久久久 | 伊人天天狠天天添日日拍 | 超碰人人草 | 深夜视频久久 | 91视频免费看网站 | 成人黄色在线视频 | 91精品国产综合久久婷婷香蕉 | 国产精品理论在线观看 | www,黄视频| 亚洲精品在线二区 | 久久精品99国产精品亚洲最刺激 | 国产亚洲精品精品精品 | 久久国产精品99久久久久久老狼 | 亚洲在线激情 | 国产黄网站在线观看 | 久久99精品国产麻豆宅宅 | 欧美亚洲一区二区在线 | 91视频亚洲 | 成人在线黄色电影 | 999在线精品 | 97涩涩视频 | 久久精品区 | 天天干天天射天天插 | 免费看久久久 | 特级西西www44高清大胆图片 | 久草久视频 | 国产成人精品一区二区三区在线 | 国产精品嫩草影院99网站 | 97精品国产91久久久久久久 | 久久综合五月婷婷 | 99精品免费久久久久久久久 | 国内精品在线看 | 色噜噜日韩精品一区二区三区视频 | 人人干人人超 | 亚洲精品国产电影 | 国产直播av | 色六月婷婷 | 久久免费久久 | 日韩精品观看 | 99热 精品在线 | 天天插天天爱 | 97高清视频| 99热手机在线| 日韩电影一区二区在线 | 日韩av三区| 三级黄色免费 | 国产精品免费久久久久影院仙踪林 | 最新国产在线观看 | 久久黄色免费视频 | 国产不卡在线播放 | 国产麻豆精品在线观看 | 精品国模一区二区三区 | 国产99自拍 | 中文字幕欧美日韩va免费视频 | 国产永久免费观看 | 色综合天天狠天天透天天伊人 | 午夜在线免费视频 | 成人久久久电影 | 日韩成人在线一区二区 | 在线观看视频精品 | 国产又粗又猛又爽 | 奇米影视777影音先锋 | 国产精品免费视频一区二区 | 国产91在线 | 美洲 | av线上看 | 成年人视频在线免费播放 | 最新中文字幕在线观看视频 | 91av视频在线播放 | 国产在线观看不卡 | 一区二区久久 | 在线观看精品一区 | 久久国产精品精品国产色婷婷 | 国产成人一级 | 97**国产露脸精品国产 | 亚洲精品99久久久久久 | 三级视频国产 | 国产日韩在线观看一区 | 亚洲精选久久 | 最近日本mv字幕免费观看 | 久久99精品国产麻豆婷婷 | 在线视频久久 | 在线看岛国av| 不卡电影免费在线播放一区 | 99视频在线精品国自产拍免费观看 | 国产中文在线观看 | 丁香网婷婷 | 国产成人精品电影久久久 | 久草网站在线观看 | 在线看片一区 | 岛国精品一区二区 | 久久国产精品偷 | 精品国产美女 | 欧美亚洲成人xxx | 久久精品国产精品亚洲 | 亚洲午夜剧场 | 国产高清中文字幕 | 女人18精品一区二区三区 | 一区二区视频欧美 | а天堂中文最新一区二区三区 | 午夜色大片在线观看 | 亚洲欧洲国产视频 | www.色午夜,com | 国产高清在线 | 亚洲精品欧美视频 | 中文字幕免费观看视频 | 国内精品毛片 | 日韩视频中文字幕 | 在线免费观看国产黄色 | 久久午夜电影网 | 一级做a爱片性色毛片www | 天天操天天操天天操天天操 | 九草视频在线观看 | 日本婷婷色 | 亚洲一区日韩精品 | a√国产免费a| 久久午夜羞羞影院 | 中文字幕亚洲在线观看 | 成人蜜桃网 | 国产精品一区免费观看 | 天天射天天干 | 亚洲成年片 | 欧美一区免费观看 | 国产欧美在线一区二区三区 | 在线小视频国产 | 亚洲欧美成人在线 | 日日夜夜中文字幕 | 欧美日韩18| 九色精品在线 | 99热精品久久 | 国产精品高潮呻吟久久久久 | 国产亚洲精品久久久久久网站 | 91成人短视频在线观看 | 国产99久| 亚洲成av人片在线观看香蕉 | 97精品国产97久久久久久粉红 | 国产视频在线免费 | av一级一片 | www.天天干.com | 黄毛片在线观看 | 久久综合免费视频 | 精品在线亚洲视频 | 欧美久草视频 | 日韩理论片在线观看 | 中文区中文字幕免费看 | 青青河边草手机免费 | 天天干天天草 | 国产小视频在线观看 | 少妇性aaaaaaaaa视频 | 国产精品九九九九九九 | av一级片在线观看 | 人人爽夜夜爽 | 国产精品一区二区三区电影 | 国产在线传媒 | 波多野结衣网址 | 手机av电影在线观看 | 激情深爱五月 | 少妇高潮冒白浆 | 麻豆一二三精选视频 | 啪啪激情网 | 亚洲每日更新 | 国产热re99久久6国产精品 | 精品国产一区二区三区久久久 | 粉嫩av一区二区三区免费 | 亚洲精品av在线 | 99精品美女 | 欧美日韩视频观看 | 成人国产精品入口 | 麻豆久久 | 激情图片区 | 三级视频国产 | 亚洲人人爱| 五月婷婷开心 | 日韩欧美视频免费在线观看 | 中文字幕在线高清 | 人人干狠狠干 | 精品久久久免费视频 | 深爱激情婷婷网 | 福利视频午夜 | 欧美日韩不卡一区二区三区 | 黄色小说18 | 精品久久九九 | 天天综合日| 精品一二三区 | 日本性视频 | 国产91探花 | 高清av免费看 | 黄色成年网站 | 天天色宗合 | 香蕉影视app | 97国产精品视频 | 国产成人av电影在线观看 | 精品久久久久久久久久 | 成人久久视频 | 欧美日韩免费视频 | 欧美日韩国产精品一区二区三区 | 欧美日韩在线精品一区二区 | 亚洲精品乱码久久久久v最新版 | 亚洲一级免费观看 | 97视频在线看 | 精品视频成人 | 99精品视频网 | 免费看污污视频的网站 | 国产精品av免费在线观看 | 日韩高清国产精品 | 天天看天天干天天操 | 国产91九色视频 | 91精品视频在线播放 | 亚洲精品大全 | 久久精品99国产精品 | 天天操福利视频 | aa一级片| 一区精品在线 |