久久精品国产精品国产精品污,男人扒开添女人下部免费视频,一级国产69式性姿势免费视频,夜鲁夜鲁很鲁在线视频 视频,欧美丰满少妇一区二区三区,国产偷国产偷亚洲高清人乐享,中文 在线 日韩 亚洲 欧美,熟妇人妻无乱码中文字幕真矢织江,一区二区三区人妻制服国产

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 运维知识 > Android >内容正文

Android

深入探索Android内存优化

發布時間:2024/1/8 Android 26 豆豆
生活随笔 收集整理的這篇文章主要介紹了 深入探索Android内存优化 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

前言
成為一名優秀的Android開發,需要一份完備的知識體系,在這里,讓我們一起成長為自己所想的那樣~。
本篇是Android內存優化的進階篇,難度會比較大,建議對內存優化不是非常熟悉的前仔細看看在前幾篇文章中,筆者曾經寫過的一篇Android性能優化之內存優化,其中詳細分析了以下幾大模塊:

Android的內存管理機制
優化內存的意義
避免內存泄漏
優化內存空間
圖片管理模塊的設計與實現
如果你對以上基礎內容都比較了解了,那么我們便開始接下來的Android內存優化探索之旅吧。

一、內存優化相關概念
Android的給每個應用進程分配的內存都是非常有限的,那么為什么不能把圖片下載來都放到磁盤中呢?那是因為放在內存中,展示會更“快”,快的原因有兩點:

硬件快:內存本身讀取、存入速度快。
復用快:解碼成果有效保存,復用時,直接使用解碼后對象,而不是再做一次圖像解碼。
這里說一下解碼的概念。Android系統要在屏幕上展示圖片的時候只認“像素緩沖”,而這也是大多數操作系統的特征。而我們常見的jpg,png等圖片格式,都是把“像素緩沖”使用不同的手段壓縮后的結果,所以這些格式的圖片,要在設備上展示,就必須經過一次解碼,它的執行速度會受圖片壓縮比、尺寸等因素影響。(官方建議:把從內存淘汰的圖片,降低壓縮比存儲到本地,以備后用,這樣可以最大限度地降低以后復用時的解碼開銷。)

接下來,我們來了解一下內存優化的一些重要概念。

手機RAM:
手機不使用PC的DDR內存,采用的是LPDDR RAM,即”低功耗雙倍數據速率內存“。

LPDDR系列的帶寬 = 時鐘頻率 ??內存總線位數 / 8
LPDDR4 = 1600MHZ ??64 / 8 ??雙倍速率 = 25.6GB/s。
那么內存占用是否越少越好?
當系統內存充足的時候,我們可以多用一些獲得更好的性能。當系統內存不足的時候,希望可以做到”用時分配,及時釋放“。

內存優化的緯度
對于Android內存優化來說又可以細分為兩個維度:

1、RAM優化
主要是降低運行時內存。它的目的如下:

防止應用發生OOM。
降低應用由于內存過大被LMK機制殺死的概率。
避免不合理使用內存導致GC次數增多,從而導致應用發生卡頓。
2、ROM優化
降低應用占ROM的體積。APK瘦身。它的目的為:

降低應用占用空間,避免因ROM空間不足導致程序無法安裝
內存問題
那么,內存問題主要是有哪幾類呢?下面我來一一敘述:

1、內存抖動
內存波動圖形呈鋸齒張、GC導致卡頓。

這個問題在Dalvik虛擬機上會更加明顯,而ART虛擬機在內存管理跟回收策略上都做了大量優化,內存分配和GC效率相比提升了5~10倍。

2、內存泄漏
對象被持有導致無法釋放或不能按照對象正常的生命周期進行釋放。

可用內存減少、頻繁GC,容易導致內存泄漏。

3、內存溢出
OOM、程序異常。

二、常見工具選擇
在內存優化的上一篇我們已經介紹過了相關的工具,這里再簡單回憶一下。

1、Memory Profiler
它的作用如下:

實時圖表展示應用內存使用量
識別內存泄漏、抖動等
提供捕獲堆轉儲、強制GC以及根據內存分配的能力
它的優點即:

方便直觀
線下使用
2、Memory Analyzer
強大的Java Heap分析工具,查找內存泄漏及內存占用
生成整體報告、分析問題等。建議線下深入使用。

3、LeakCanary
自動內存泄漏檢測神器。僅用于線下集成。

它的缺點比較明顯,雖然使用了idleHandler與多進程,但是dumphprof的SuspendAll Thread的特性依然會導致應用卡頓。
在三星等手機,系統會緩存最后一個Activity,此時應該采用更嚴格的檢測模式。

4、那么如何定制線上的LeakCanary?
定制LeakCanary其實就是對haha組件來進行定制。haha庫是square出品的一款自動分析Android堆棧的java庫。haha庫的鏈接地址。

它的基本用法如下所示:

// 導出堆棧文件
File heapDumpFile = …
Debug.dumpHprofData(heapDumpFile.getAbsolutePath());
// 根據堆棧文件創建出內存映射文件緩沖區
DataBuffer buffer = new MemoryMappedFileBuffer(heapDumpFile);
// 根據文件緩存區創建出對應的快照
Snapshot snapshot = Snapshot.createSnapshot(buffer);

// 從快照中獲取指定的類
ClassObj someClass = snapshot.findClass(“com.example.SomeClass”);
在實現線上版的LeakCanary的時候主要要做2個工作:

1、在過程中加上對大對象的分析過程。
2、解決掉將hprof文件映射到內存中的時候可能內存暴漲的問題。
5、實現內存泄漏監控閉環
在實現了線上版的LeakCanary之后,就需要將線上版的LeakCanary與服務器和前端頁面結合起來。例如,當LeakCanary上發現內存泄漏時,手機將上傳內存快照至服務器,此時服務器分析Hprof,如果不是系統原因導致誤報則通過git得到該最近修改人,最后將內存泄漏bug單提交給負責人。該負責人通過前端實現的bug單系統即可看到自己新增的bug。

三、Android內存管理機制回顧
ART和Dalvik虛擬機使用分頁和內存映射來管理內存。下面我們先從Java的內存分配開始說起。

1、Java內存分配
Java的內存分配區域為如下幾部分:

方法區:主要存放靜態常量
虛擬機棧:Java變量引用
本地方法棧:native變量引用
堆:對象
程序計數器:計算當前線程的當前方法執行到多少行
2、Java內存回收算法
1、標記-清除算法
流程可簡述為兩步:

標記所有需要回收的對象
統一回收所有被標記的對象
它的優點實現比較簡單,缺點也很明顯:

標記、清除效率不高
產生大量內存碎片
2、復制算法
流程可簡述為三步:

將內存劃分為大小相等的兩塊
一塊內存用完之后復制存活對象到另一塊
清理另一塊內存
它的優點為 實現簡單,運行高效,每次僅需遍歷標記一半的內存區域。而缺點則會浪費一半空間,代價大。

3、標記-整理算法
流程可簡述為三步:

標記過程與”標記-清除算法“一樣
存活對象往一端進行移動
清理其余內存
它的優點如下:

避免標記-清除導致的內存碎片
避免復制算法的空間浪費
4、分代收集算法
現在主流的虛擬機一般用的比較多的還是分帶收集算法,它具有如下特點:

結合多種算法優勢
新生代對象存活率低,復制
老年代對象存活率高,標記-整理
3、Android內存管理機制
Android中的內存是彈性分配的,分配值與最大值受具體設備影響。

對于OOM場景其實由細分為兩種,一種是內存真正不足
了,二另一種則是可用內存不足。要注意一下這兩種的區分。

以Android中的虛擬機的角度來說,我們要清楚Dalvik與Art區別,Dalvik僅固定一種回收算法,而Art回收算法可運行期選擇,并且,Art具備內存整理能力,減少內存空洞。

最后,LMK機制(Low Memory killer)保證了進程資源的合理利用,它的實現原理主要是根據進程分類和回收收益來綜合決定的。

四、內存抖動
當內存頻繁分配和回收導致內存不穩定,就會出現內存抖動,它通常表現為 頻繁GC、內存曲線呈鋸齒狀。

它的危害也很嚴重,通常會導致頁面卡頓,甚至造成OOM。

那么為什么內存抖動會導致OOM?
主要原因有兩點:

頻繁創建對象,導致內存不足及碎片(不連續)
不連續的內存片無法被分配,導致OOM
內存抖動解決實戰
點擊按鈕使用handler發送一個空消息,handler的handleMessage接收到消息后創建內存抖動:即在for循環創建100個容量為10萬的strings數組并在30ms后繼續發送空消息。

一般使用Memory Profiler或CPU Profiler結合代碼排查即可找到內存抖動出現的地方。

通常的技巧就是著重查看循環或頻繁調用的地方。

下面列舉一些導致內存抖動的常見案例:

1、字符串使用加號拼接:
使用StringBuilder替代。
初始化時設置容量,減少StringBuilder的擴容。
2、資源復用
使用全局緩存池,以重用頻繁申請和釋放的對象。
注意結束使用后,需要手動釋放對象池中的對象。
3、減少不合理的對象創建
ondraw、getView中對象的創建盡量進行復用。
避免在循環中不斷創建局部變量。
4、使用合理的數據結構
使用SparseArray類族來替代HashMap。

五、內存優化體系搭建
在開始我們今天正式的主題之前,我們先來回歸一下內存泄漏的概念與解決技巧。

所謂的內存泄漏就是內存中存在已經沒有用的對象。它的表現一般為 內存抖動、可用內存逐漸減少。
它的危害即會導致內存不足、GC頻繁、OOM。

內存泄漏的分析一般可簡述為兩步:

1、使用Memory Profiler初步觀察。
2、通過Memory Analyzer結合代碼確認。
1、MAT回顧
MAT查找內存泄漏
首先找到當前Activity,在Histogram中選擇其List Objects中的 with incoming reference(哪些強引用引向了我),然后選擇當前的一個Path to GC Roots/Merge to GC Roots的exclude All 弱軟虛引用。最后找到最后的泄漏對象在左下角下會有一個小圓圈。

MAT的關鍵使用細節
要全面掌握MAT的用法,必須先了解下面的一些細節:

善于使用Regex查找對應泄漏類。
使用group by package查找對應包下的具體類。
其次,要明白with outgoing references和with incoming references的區別。

with outgoing references為它引用了哪些對象,with incoming references為哪些對象引用了它。

還需要了解Shallow Heap和Retained Heap的區別。

Shallow Heap為對象自身占用的內存,而Retained Heap則還包含對象引用的對象所占用的內存。

除此之外,MAT共有5個關鍵組件幫助我們去分析內存方面的問題,他們分別是Dominator_tree
、Histogram、thread_overview、Top Consumers、Leak Suspects。下面我們簡單地了解一下它們。

Dominator(支配者):
如果從GC Root到達對象A的路徑上必須經過對象B,那么B就是A的支配者。

Histogram和dominator_tree的區別:
Histogram顯示Shallow Heap、Retained Heap、Objects,而dominator_tree顯示的是Shallow Heap、Retained Heap、Percentage。
Histogram基于類的角度,dominator_tree是基于實例的角度。Histogram不會具體顯示每一個泄漏的對象,而dominator_tree會。
thread_overview
查看有多少線程和線程的Shallow Heap、Retained Heap、Context Class Loader與is Daemon。

Top Consumers
通過圖形的形式列出占用內存比較多的對象。

在下方的Biggest Objects還可以查看其相對比較詳細的信息,如Shallow Heap、Retained Heap。

Leak Suspects
列出有內存泄漏的地方,點擊Details可以查看其產生內存泄漏的引用鏈。

最后,我列舉一些內存泄漏優化的技巧:

1、使用類似Hack的方式修復系統內存泄漏:
LeakCanary的AndroidExcludeRefs列出了一些由于系統原因導致引用無法釋放的例子,可使用類似Hack的方式去修復。
2、Activity的兜底內存回收策略:
在Activity的onDestory中遞歸釋放其引用到的Bitmap、DrawingCache等資源,降低發生內存泄漏對應用內存的壓力。
2、建立線上內存泄漏監控組件:使用定制化的LeakCanary
在線上也可以使用類似LeakCanary的自動化檢測方案,但是需要對生成的Hprof內存快照文件做一些優化,裁剪大部分圖片對應的byte數據以減少文件開銷,最后使用7zip壓縮,一般可節省90%大小。

3、建立線上OOM監控組件:Probe
美團Android內存泄漏自動化鏈路分析組件Probe
在OOM時生成Hprof內存快照,然后通過單獨進程對這個文件做進一步分析。

它的缺點比較多,具體為如下幾點:

在崩潰的時候生成內存快照容易導致二次崩潰。
部分手機生成Hprof快照比較耗時。
部分OOM是由虛擬內存不足導致。
在實現自動化鏈路分析組件Probe的過程中主要要解決如下問題:

1、鏈路分析時間過長
使用鏈路歸并,將具有相同層級與結構的鏈路進行合并。
使用自適應擴容法,通過不斷比較現有鏈路和新鏈路,結合擴容因子,逐漸完善為完整的泄漏鏈路。
2、分析進程占用內存過大
分析進程占用的內存跟內存快照文件的大小不成正相關,而跟內存快照文件的Instance數量呈正相關。所以應該盡可能排除不需要的Instance實例。

Prope分析流程
1、hprof 映射到內存 -> 解析成Snapshot & 計數壓縮:

解析后的Snapshot中的Heap有四種類型,具體為:

DefaultHeap
ImageHeap
App Heap:包括ClassInstance、ClassObj、ArrayInstance、RootObj。
System Heap
解析完后使用了計數壓縮策略,對相同的Instance使用計數,以減少占用內存。超過計數閾值的需要計入計數桶(計數桶記錄了丟棄個數和每個Instance的大小)。

2、生成Dominator Tree。

3、計算RetainSize。

4、生成Reference鏈 & 基礎數據類型增強:

如果對象是基礎數據類型,會將自身的RetainSize累加到父節點上,將懷疑對象替換為它的父節點。

5、鏈路歸并。

6、計數桶補償 & 基礎數據類型和父節點融合:

使用計數補償策略計算RetainSize,主要是判斷對象是否在計數桶中,如果在的話則將丟棄的個數和大小補償到對象上,累積計算RetainSize,最后對RetainSize排序以查找可疑對象。

7、排序擴容。

8、查找泄露鏈路。

總體架構圖如下:

image

4、實現單機版的Profile - Memory自動化內存分析
項目地址點擊此處

在配置的時候要注意兩個問題:

1、liballoc-lib.so在構建后工程的build->intermediates->cmake目錄下。將對應的cpu abi目錄拷貝到新建的libs目錄下。
2、在DumpPrinter Java庫的build.gradle中的jar閉包中需要加入以下代碼以識別源碼路徑
sourceSets.main.java.srcDirs = [‘src’]
具體的使用步驟如下:

1、點擊”開
始記錄“按鈕可以看到觸發對象分配的記錄,說明對象已經開始記錄對象的分配。

12-26 10:54:03.963 30450-30450/com.dodola.alloctrack I/AllocTracker: current alloc count 388=
2、然后,點擊多次”生成1000個對象“按鈕,當對象達到設置的最大數量的時候觸發內存dump,會得到保存數據路徑的日志。

12-26 10:54:03.963 30450-30450/com.dodola.alloctrack I/AllocTracker: current alloc count 388=
12-26 10:56:45.103 30450-30450/com.dodola.alloctrack I/AllocTracker: saveARTAllocationData write file to /storage/emulated/0/crashDump/1577329005
3、可以看到數據保存在sdk下的crashDump目錄下。

4、此時,通過gradle task :buildAlloctracker任務編譯出存放在tools/DumpPrinter-1.0.jar的dump工具,然后采用如下命令來將數據解析到dump_log.txt文件中。

java -jar tools/DumpPrinter-1.0.jar dump文件路徑 > dump_log.txt
5、最后,就可以在dump_log.txt文件中看到解析出來的數據,如下所示:

Found 4949 records:
tid=1 byte[] (94208 bytes)
dalvik.system.VMRuntime.newNonMovableArray (Native method)
android.graphics.Bitmap.nativeCreate (Native method)
android.graphics.Bitmap.createBitmap (Bitmap.java:975)
android.graphics.Bitmap.createBitmap (Bitmap.java:946)
android.graphics.Bitmap.createBitmap (Bitmap.java:913)
android.graphics.drawable.RippleDrawable.updateMaskShaderIfNeeded (RippleDrawable.java:776)
android.graphics.drawable.RippleDrawable.drawBackgroundAndRipples (RippleDrawable.java:860)
android.graphics.drawable.RippleDrawable.draw (RippleDrawable.java:700)
android.view.View.getDrawableRenderNode (View.java:17736)
android.view.View.drawBackground (View.java:17660)
android.view.View.draw (View.java:17467)
android.view.View.updateDisplayListIfDirty (View.java:16469)
android.view.ViewGroup.recreateChildDisplayList (ViewGroup.java:3905)
android.view.ViewGroup.dispatchGetDisplayList (ViewGroup.java:3885)
android.view.View.updateDisplayListIfDirty (View.java:16429)
android.view.ViewGroup.recreateChildDisplayList (ViewGroup.java:3905)
5、圖片監控體系搭建
在介紹圖片監控體系的搭建之前,首先我們來回顧下Android Bitmap內存分配的變化:

在Android 3.0之前

Bitmap對象存放在Java Heap,而像素數據是存放在Native內存中的。
如果不手動調用recycle,Bitmap Native內存的回收完全依賴finalize函數回調,但是回調時機是不可控的。
Android 3.0 ~ Android 7.0

將Bitmap對象和像素數據統一放到Java Heap中,即使不調用recycle,Bitmap像素數據也會隨著對象一起被回收。

Bitmap全部放在Java Heap中的缺點很明顯:

1、Bitmap是內存消耗的大戶,而Max Java Heap一般限制為256、512MB,Bitmap過大過多容易導致OOM。
2、容易引起大量GC,沒有充分利用系統的可用內存。
Android 8.0及之后

使用了能夠輔助回收Native內存的NativeAllocationRegistry,以實現將像素數據放到Native內存中,并且可以和Bitmap對象一起快速釋放,最后,在GC的時候還可以考慮這些Bitmap內存以防止被濫用。
Android 8.0為了解決圖片內存占用過多和圖像繪制效率過慢的問題新增了硬件位圖Hardware Bitmap。
那么,如何將圖片內存存放在Native中呢?
1、調用libandroid_runtime.so中的Bitmap構造函數,申請一張空的Native Bitmap。對于不同Android版本而言,這里的獲取過程都有一些差異需要適配。
2、申請一張普通的Java Bitmap。
3、將Java Bitmap的內容繪制到Native Bitmap中。
4、釋放Java Bitmap內存。
我們都知道,當系統內存不足,LMK會根據OOM_adj開始殺進程,從后臺、桌面、服務、前臺,直到手機重啟。并且,如果頻繁申請釋放Java Bitmap也很容易導致內存抖動。對于這種種問題,我們如何評估內存對應用性能的影響呢?

主要從以下兩個方面進行評估:

1、崩潰中異常退出和OOM的比例。
2、低內存設備更容易出現內存不足和卡頓,需要查看應用中用戶的手機內存在2GB以下所占的比例。
對于具體的優化策略,我們可以從以下幾個方面來進行。

1、設備分級
內存優化首先需要根據設備環境來綜合考慮,讓高端設備使用更多的內存,做到針對設備性能的好壞使用不同的內存分配和回收策略。

使用類似device-year-class的策略對設備進行分級,對于低端機用戶可以關閉復雜的動畫或”重功能“,使用565格式的圖片或更小的緩存內存等。

業務開發人員需要考慮功能是否對低端機開啟,在系統資源不夠時主動去做降級處理。

2、建立統一的緩存管理組件
建立統一的緩存管理組件,合理使用OnTrimMemory回調,根據系統不同的狀態去釋放相應的內存。

在實現過程中,需要解決使用static LRUCache來緩存大尺寸Bitmap等問題。

并且,在通過實際的測試后,發現onTrimMemory的ComponetnCallbacks2.TRIM_MEMORY_COMPLETE并不等價于onLowMemory,因此建議仍然要去監聽onLowMemory回調。

3、低端機避免使用多進程
一個空進程也會占用10MB內存,低端機應該盡可能減少使用多進程。

針對低端機用戶可以推出4MB的輕量級版本,如今日頭條極速版、Facebook Lite。

4、統一圖片庫
需要收攏圖片的調用,避免使用Bitmap.createBitmap、BitmapFactory相關的接口創建Bitmap,應該使用自己的圖片框架。

5、線下大圖片檢測
在開發過程中,如果檢測到不合規的圖片使用(如圖片寬度超過View的寬度甚至圖片寬度),應該立刻提示圖片所在的Activity和堆棧,讓開發人員更快發現并解決問題。在灰度和線上環境,可以將異常信息上報到后臺,還可以計算超寬率(圖片超過屏幕大小所占圖片總數的比例)。

常規實現:

繼承ImageView,重寫實現計算圖片大小。但是侵入性強,并且不通用。

下面介紹一下ARTHook的方案。

ARTHook優雅檢測大圖

ARTHook,即掛鉤,用額外的代碼勾住原有的方法,以修改執行邏輯,主要用于以下幾方面:

1、AOP變成
2、運行時插樁
3、性能分析
4、安全審計
具體我們是使用Epic來進行Hook,Epic是一個虛擬機層面,以Java方法為粒度的運行時Hook框架。簡單來說,它就是ART上的Dexposed,并且它目前支持Android 4.0~10.0。

Epic github地址

Epic的使用可簡述為:

1、在build.gradle中添加

compile ‘me.weishu:epic:0.6.0’
2、繼承XC_MethodHook,實現Hook方法前后的邏輯。如監控Java線程的創建和銷毀:

class ThreadMethodHook extends XC_MethodHook{
@Override
protected void beforeHookedMethod(MethodHookParam param) throws Throwable {
super.beforeHookedMethod(param);
Thread t = (Thread) param.thisObject;
Log.i(TAG, “thread:” + t + “, started…”);
}

@Override protected void afterHookedMethod(MethodHookParam param) throws Throwable {super.afterHookedMethod(param);Thread t = (Thread) param.thisObject;Log.i(TAG, "thread:" + t + ", exit.."); }

}
3、注入Hook好的方法:

DexposedBridge.findAndHookMethod(Thread.class, “run”, new ThreadMethodHook());
知道了Epic的基本使用方法之后,我們便可以利用它來進行大圖片的監控報警了。

以Awesome-WanAndroid項目為例,首先,在WanAndroidApp的onCreate方法中添加如下代碼:

DexposedBridge.hookAllConstructors(ImageView.class, new XC_MethodHook() {
@Override
protected void afterHookedMethod(MethodHookParam param) throws Throwable {
super.afterHookedMethod(param);
// 這里找到所有通過ImageView的setImageBitmap方法設置的切入點,
// 其中最后一個參數ImageHook對象是繼承了XC_MethodHook類以便于
// 重寫afterHookedMethod方法拿到相應的參數進行監控邏輯的判斷
DexposedBridge.findAndHookMethod(ImageView.class, “setImageBitmap”, Bitmap.class, new ImageHook());
}
});
接下來,我們來實現我們的ImageHook類,如下所示:

public class ImageHook extends XC_MethodHook {

@Override protected void afterHookedMethod(MethodHookParam param) throws Throwable {super.afterHookedMethod(param);// 實現我們的邏輯ImageView imageView = (ImageView) param.thisObject;checkBitmap(imageView,((ImageView) param.thisObject).getDrawable()); }private static void checkBitmap(Object thiz, Drawable drawable) {if (drawable instanceof BitmapDrawable && thiz instanceof View) {final Bitmap bitmap = ((BitmapDrawable) drawable).getBitmap();if (bitmap != null) {final View view = (View) thiz;int width = view.getWidth();int height = view.getHeight();if (width > 0 && height > 0) {// 圖標寬高都大于view的2倍以上,則警告if (bitmap.getWidth() >= (width << 1)&& bitmap.getHeight() >= (height << 1)) {warn(bitmap.getWidth(), bitmap.getHeight(), width, height, new RuntimeException("Bitmap size too large"));}} else {// 當寬高度等于0時,說明ImageView還沒有進行繪制,使用ViewTreeObserver進行大圖檢測的處理。final Throwable stackTrace = new RuntimeException();view.getViewTreeObserver().addOnPreDrawListener(new ViewTreeObserver.OnPreDrawListener() {@Overridepublic boolean onPreDraw() {int w = view.getWidth();int h = view.getHeight();if (w > 0 && h > 0) {if (bitmap.getWidth() >= (w << 1)&& bitmap.getHeight() >= (h << 1)) {warn(bitmap.getWidth(), bitmap.getHeight(), w, h, stackTrace);}view.getViewTreeObserver().removeOnPreDrawListener(this);}return true;}});}}} }private static void warn(int bitmapWidth, int bitmapHeight, int viewWidth, int viewHeight, Throwable t) {String warnInfo = "Bitmap size too large: " +"\n real size: (" + bitmapWidth + ',' + bitmapHeight + ')' +"\n desired size: (" + viewWidth + ',' + viewHeight + ')' +"\n call stack trace: \n" + Log.getStackTraceString(t) + '\n';LogHelper.i(warnInfo); }

}
在上面,我們重寫了ImageHook的afterHookedMethod方法,拿到了當前的ImageView和要設置的Bitmap對象,如果當前ImageView的寬高大于0,我們便進行大圖檢測的處理:ImageView的寬高都大于View的2倍以上,則警告,如果當前ImageView的寬高等于0,則說明ImageView還沒有進行繪制,則使用ImageView的ViewTreeObserer獲取其寬高進行大圖檢測的處理。至此,我們的大圖檢測檢測組件就實現了。

ARTHook方案實現小結

1、無侵入性
2、通用性強
3、兼容性問題大,開源方案不能帶到線上環境。
6、線下重復圖片檢測
項目地址

首先我們來了解一下這里的重復圖片所指的概念:
即Bitmap像素數據完全一致,但是有多個不同的對象存在。

使用內存Hprof分析工具,自動將重復Bitmap的圖片和引用堆棧輸出。具體實現步驟如下:

1、獲取 android.graphics.Bitmap 實例對象的 mBuffer 為 ArrayInstance ,通過 getValues 獲取數據為 Object 類型,后面計算 md5 需要為 byte[] 類型,所以通過反射的方式調用 ArrayInstance#asRawByteArray 直接返回 byte[] 數據。
2、根據 mBuffer 的數據生成 png 圖片文件,參考了 https://github.com/JetBrains/adt-tools-base/blob/master/ddmlib/src/main/java/com/android/ddmlib/BitmapDecoder.java 實現。
3、獲取堆棧信息,直接使用LeakCanary獲取stack的方法,使用leakcanary-analyzer-1.6.2.jar 和 leakcanary-watcher-1.6.2.jar 這兩個庫文件。并用反射的方式調用了HeapAnalyzer#findLeakTrace 方法。
其中,獲取堆棧的信息也可以直接使用haha庫來進行獲取。這里簡單說一下使用haha庫獲取堆棧的流程。

1、預備一個已經存在重復bitmap的hprof文件。
2、利用HAHA庫上的MemoryMappedFileBuffer讀取hrpof文件 [關鍵代碼 new MemoryMappedFileBuffer(heapDumpFile) ]
3、解析生成snapshot,獲取heap,這里我只獲取了app heap [關鍵代碼 snapshot.getHeaps(); heap.getName().equals(“app”) ]
4、從snapshot中根據指定class查找出所有的Bitmap Classes [關鍵代碼snapshot.findClasses(Bitmap.class.getName()) ]
5、從heap中獲得所有的Bitmap實例instance [關鍵代碼 clazz.getHeapInstances(heap.getId()) ]
6、根據instance中獲取所有的屬性信息Field[],并從Field[]查找出我們需要的”mWidth” “mHeight” “mBuffer”信息
7、通過”mBuffer”屬性即可獲取他們的hashcode來判斷相同
8、最后通過instance中mNextInstanceToGcRoot獲取整個引用鏈信息并打印。
在實現圖片內存監控的過程中,應注意一下兩點:

1、在線上可以按照不同的系統、屏幕分辨率等緯度去分析圖片內存的占用情況。
2、在OOM崩潰時,可以將圖片總內存、Top N圖片占用內存寫入崩潰日志。
7、建立全局Bitmap監控
為了建立全局的Bitmap監控,我們必須對Bitmap的分配和回收進行追蹤。我們先來看看Bitmap有哪些特點:

創建場景比較單一:在Java層調用Bitmap.create或BitmapFactory等方法創建,可以封裝一層對Bitmap創建的接口,注意要包含調用外部庫產生的Bitmap。
創建頻率比較低。
和Java對象的生命周期一樣服從GC,可以使用WeakReference來追蹤Bitmap的銷毀。
根據以上特點,我們可以建立一套Bitmap的高性價比監控組件:

1、首先,在接口層將所有創建出來的Bitmap放入一個WeakHashMap中,并記錄創建Bitmap的數據、堆棧等信息,然后每隔一定時間查看WeakHashMap中有哪些Bitmap仍然存活來判斷是否出現Bitmap濫用或泄漏。
2、這個方案性能消耗很低,可以在正式環境中進行。注意正式與測試環境需要采用不同程度的監控。
6、建立全局的線程監控組件
每個線程初始化都需要mmap一定的棧大小,在默認情況下初始化一個線程需要mmap 1MB左右的內存空間,在32bit的應用中有4g的vmsize,實際能使用的有3g+,這樣一個進程最大能創建的線程數可以達到3000個,但是linux對每個進程可創建的線程數也有一定的限制(/proc/pid/limits),并且不同廠商也能修改這個限制,超過該限制就會OOM。

對線程數量的限制,一定程度上可以避免OOM的發生。

線程監控組件的實現原理
在線下或灰度的環境下通過一個定時器每隔10分鐘dump出應用所有的線程相關信息,當線程數超過當前閾值時,將當前的線程信息上報并預警。

7、建立線上應用內存監控體系
具體的相關數據獲取方式如下:

1、首先,ActivityManager的getProcessMemoryInfo -> Debug.MemoryInfo數據。
2、通過hook Debug.MemoryInfo的getMemoryStat方法(os v23及以上)可以獲得Memory Profiler中的多項數據,進而獲得細分內存使用情況。
3、通過Runtime獲取DalvikHeap。
4、通過Debug.getNativeHeapAllocatedSize獲取NativeHeap。
對于監控場景,需要劃分為兩大類:

1、常規內存監控
根據斐波那契數列每隔一段時間(max:30min)獲取內存的使用情況。內存監控方法有多種實現方式,我們先來介紹幾種常規方式。

針對場景進行線上Dump內存的方式:

具體使用Debug.dumpHprofData()實現。

其實現的流程為:

1、超過最大內存的80%
2、內存Dump
3、回傳文件
4、MAT手動分析
但是有如下缺點:

1、Dump文件太大,和對象數正相關,可以進行裁剪。
2、上傳失敗率高,分析困難。
LeakCanary帶到線上的方式:

預設泄漏懷疑點,一旦發現泄漏進行回傳。但這種實現方式缺點比較明顯:

不適合所有情況,需要預設懷疑點。
分析比較耗時,容易導致OOM。
定制LeakCanary方式

定制LeakCanary需要解決以上產生的一些問題,下面這里分別列出對應的解決方案:

1、預設懷疑點->自動找懷疑點。
2、分析泄漏鏈路慢->分析Retain size大的對象。
3、分析OOM->對象裁剪,不全部加載到內存。
2、低內存監控
利用onLowMemory、onTrimMemory監聽物理內存警告。
代碼設置超過虛擬內存大小最大限制的90%則直接觸發內存警告。
對于監控指標,一般為:發生頻率、發生時各項內存使用狀況、發生時App的當前場景。
并且,為了準確衡量內存性能,我們引入了內存異常率和觸頂率的指標。

內存異常率

內存UV異常率 = PSS 超過400MB的UV / 采集UV,PSS獲取:通過Debug.MemoryInfo。

如果出現新的內存使用不當或內存泄漏的場景,這個指標會有所上漲。

觸頂率

內存UV觸頂率 = Java堆占用超過最大堆限制的85%的UV / 采集UV

計算觸頂率的代碼如下所示:

long javaMax = Runtime.maxMemory();
long javaTotal = Runtime.totalMemory();
long javaUsed = javaTotal - runtime.freeMemory();
float proportion = (float) javaUsed / javaMax;
如果超過85%最大堆限制,GC會變得更加頻發,容易造成OOM和卡頓。

這里小結一下,客戶端只負責上報數據,由后臺來計算平均PSS、圖片內存、Java內存、異常率、觸頂率等指標值,這樣便可以通過版本對比來監控是否有新增內存問題。因此,建立線上監控完整方案需包含以下幾點:

待機內存、重點模塊內存、OOM率。
整體及重點模塊GC次數、GC時間。
增強的LeakCanry自動化內存泄漏分析。
低內存監控模塊的設置。
8、GC監控組件搭建
通過Debug.startAllocCounting來監控GC情況,注意有一定性能影響。

在Android 6.0之前可以拿到內存分配次數和大小以及GC次數,代碼如下所示:

long allocCount = Debug.getGlobalAllocCount();
long allocSize = Debug.getGlobalAllocSize();
long gcCount = Debug.getGlobalGcInvocationCount();
并且,在Android 6.0后可以拿到更精準的GC信息:

Debug.getRuntimeStat(“art.gc.gc-count”);
Debug.getRuntimeStat(“art.gc.gc-time”);
Debug.getRuntimeStat(“art.gc.blocking-gc-count”);
Debug.getRuntimeStat(“art.gc.blocking-gc-time”);
一般關注阻塞式GC的次數和耗時,因為它會暫停線程,可能導致應用發生卡頓。建議僅對重度場景使用。

9、設置內存兜底策略
設置內存兜底策略的目的,是為了在用戶無感知的情況下,在接近觸發系統異常前,選擇合適的場景殺死進程并將其重啟,從而使得應用內存占用回到正常情況。

一般進行執行內存兜底策略時需要滿足以下條件:

是否在主界面退到后臺且位于后臺時間超過30min。
當前時間為早上2~5點。
不存在前臺服務(通知欄、音樂播放欄等情況)。
java heap必須大于當前進程最大可分配的85% || native內存大于800MB
vmsize超過了4G(32bit)的85%。
非大量的流量消耗(不超過1M/min) && 進程無大量CPU調度情況。
滿足以上條件則殺死當前主進程并通過push進程重新拉起及初始化。

10、內存優化的一些策略
下面列舉一些我在內存優化過程中常用的一些策略。

1、使bitmap資源在native中分配:
對于Android 2.x系統,使用反射將BitmapFactory.Options里面隱藏的inNativeAlloc打開。

對于Android 4.x系統,使用Fresco將bitmap資源在native中分配。

2、使用inSampleSize避免不必要的大圖加載。
3、使用Glide、Fresco等圖片加載庫,通過定制,在加載bitmap時,若發生OOM,則使用try catch將其捕獲,然后清除圖片cache,嘗試降低bitmap format(ARGB8888、RGB565、ARGB4444、ALPHA8)。
4、前臺每隔3分鐘去獲取當前應用內存占最大內存的比例,超過設定的危險閾值(如80%)則主動釋放應用cache(Bitmap為大頭),并且顯示地除去應用的memory,以加速內存收集的過程。
計算當前應用內存占最大內存的比例的代碼如下:

max = Runtime.getRuntime().maxMemory();
available = Runtime.getRuntime.totalMemory() - Runtime.getFreeMemory();
ratio =available / max;
顯示地除去應用的memory,以加速內存收集的過程的代碼如下:

WindowManagerGlobal.getInstance().startTrimMemory(TRIM_MEMORY_COMPLETE);
5、由于webview存在內存系統泄漏,還有圖庫占用內存過多的問題,可以采用單獨的進程。
6、應用發生OOM時,需要上傳更加詳細的內存相關信息。
7、當應用使用的Service不再使用時應該銷毀它,建議使用IntentServcie。
8、當UI隱藏時釋放內存
當用戶切換到其它應用并且你的應用UI不再可見時,應該釋放應用UI所占用的所有內存資源。這能夠顯著增加系統緩存進程的能力,能夠提升用戶體驗。

在所有UI組件都隱藏的時候會接收到Activity的onTrimMemory()回調并帶有參數TRIM_MEMORY_UI_HIDDEN。

9、謹慎使用第三方庫,避免為了使用其中一兩個功能而導入一個大而全的解決方案。
六、線下Native內存泄漏監控搭建
在Android 8.0之后,可以使用Address Sanitizer、Malloc調試和Malloc鉤子進行native內存分析,參見native_memory

對于線下Native內存泄漏監控的建立,主要針對是否能重編so的情況來進行記錄分配的內存信息。

針對無法重編so的情況
使用PLT Hook攔截庫的內存分配函數,然后重定向到我們自己的實現后去記錄分配的內存地址、大小、來源so庫路徑等信息。
定期掃描分配與釋放釋放配對,對于不配對的分配輸出上述記錄的信息。
針對可重編的so情況
通過GCC的”-finstrument-functions“參數給所有函數插樁,然后在樁中模擬調用棧的入棧與出棧操作。
通過ld的”–warp“參數攔截內存分配和釋放函數,重定向到我們自己的實現后記錄分配的內存地址、大小、來源so以及插樁調用棧此刻的內容。
定期掃描分配與釋放是否配對,對于不配對的分配輸出我們記錄的信息。
七、內存優化演進
1、自動化測試階段
內存達到閾值后自動觸發Hprof Dump,將得到的Hprof存檔后由人工通過MAT進行分析。

2、LeakCanary
檢測和分析報告都在一起,批量自動化測試和事后分析不太方便。

3、使用基于LeakCannary的改進版ResourceCanary
它的主要特點如下:

1、分離檢測和分析兩部分流程
自動化測試由測試平臺進行,分析則由監控平臺的服務端離線完成,再通知相關開發解決問題。

2、裁剪Hprof文件,以降低后臺存儲Hprof的開銷
獲取需要的類和對象相關的字符串信息即可,其它數據都可以在客戶端裁剪,一般能Hprof大小會減小至原來的1/10左右。

小結
在研發階段需要不斷實現更多的工具和組件,以此系統化地提升自動化程度,以最終提升發現問題的效率。

八、內存優化工具
除了常用的內存分析工具Memory Profiler、MAT、LeakCanary之外,還有一些其它的內存分析工具,下面我將一一為大家進行介紹。

1、top
top命令是Linux下常用的性能分析工具,能夠實時顯示系統中各個進程的資源占用狀況,類似于Windows的任務管理器。top命令提供了實時的對系統處理器的狀態監視。它將顯示系統中CPU最“敏感”的任務列表。該命令可以按CPU使用、內存使用和執行時間對任務進行排序。

接下來,我們輸入以下命令查看top命令的用法:

quchao@quchaodeMacBook-Pro ~ % adb shell top --help
usage: top [-Hbq] [-k FIELD,] [-o FIELD,] [-s SORT] [-n NUMBER] [-d SECONDS] [-p PID,] [-u USER,]

Show process activity in real time.

-H Show threads
-k Fallback sort FIELDS (default -S,-%CPU,-ETIME,-PID)
-o Show FIELDS (def PID,USER,PR,NI,VIRT,RES,SHR,S,%CPU,%MEM,TIME+,CMDLINE)
-O Add FIELDS (replacing PR,NI,VIRT,RES,SHR,S from default)
-s Sort by field number (1-X, default 9)
-b Batch mode (no tty)
-d Delay SECONDS between each cycle (default 3)
-n Exit after NUMBER iterations
-p Show these PIDs
-u Show these USERs
-q Quiet (no header lines)

Cursor LEFT/RIGHT to change sort, UP/DOWN move list, space to force
update, R to reverse sort, Q to exit.
這里使用top僅顯示一次進程信息,以便來講解進程信息中各字段的含義。

image

前四行是當前系統情況整體的統計信息區。下面我們看每一行信息的具體意義。

第一行,Tasks — 任務(進程),具體信息說明如下:

系統現在共有729個進程,其中處于運行中的有1個,715個在休眠(sleep),stoped狀態的有0個,zombie狀態(僵尸)的有8個。

第二行,內存狀態,具體信息如下:

5847124k total — 物理內存總量(5.8GB)

5758016k used — 使用中的內存總量(5.7GB)

89108k free — 空閑內存總量(89MB)

112428k buffers — 緩存的內存量 (112M)

第三行,swap交換分區信息,具體信息說明如下:

2621436k total — 交換區總量(2.6GB)

612572k used — 使用的交換區總量(612MB)

2008864k free — 空閑交換區總量(2GB)

2657696k cached — 緩沖的交換區總量(2.6GB)

第四行,cpu狀態信息,具體屬性說明如下:

800%cpu - 8核CPU。

39%user - 39%CPU被用戶進程使用。

0%nice - 優先值為負的進程占0%。

42%sys — 內核空間占用CPU的百分比為42%。

712%idle - 除IO等待時間以外的其它等待時間為712%。

0%iow - IO等待時間占0%。

0%irq - 硬中斷時間占0%。

6%sirq - 軟中斷時間占0%。

對于內存監控,在top里我們要時刻監控第三行swap交換分區的used,如果這個數值在不斷的變化,說明內核在不斷進行內存和swap的數據交換,這是真正的內存不夠用了。

在第五行及以下,就是各進程(任務)的狀態監控,項目列信息說明如下:

PID — 進程id。

USER — 進程所有者。

PR — 進程優先級。

NI — nice值。負值表示高優先級,正值表示低優先級。

VIRT — 進程使用的虛擬內存總量。VIRT = SWAP + RES。

RES — 進程使用的、未被換出的物理內存大小。RES = CODE + DATA。

SHR — 共享內存大小。

S — 進程狀態。D=不可中斷的睡眠狀態、R=運行、 S=睡眠、T=跟蹤/停止、Z=僵尸進程。

%CPU — 上次更新到現在的CPU時間占用百分比。

%MEM — 進程使用的物理內存百分比。

TIME+ — 進程使用的CPU時間總計,單位1/100秒。

ARGS — 進程名稱(命令名/命令行)。

這里可以看到第一行的就是Awesome-WanAndroid這個應用的進程,它的進程名稱為json.chao.com.w+,PID為23104,進程所有者USER為u0_a714,進程優先級PR為10,nice置NI為-10。進程使用的虛擬內存總量VIRT為4.3GB,進程使用的、未被換出的物理內存大小RES為138M,共享內存大小SHR為66M,進程狀態S是睡眠狀態,上次更新到現在的CPU時間占用百分比%CPU為21.2。進程使用的物理內存百分比%MEM為2.4%,進程使用的CPU時間TIME+為1:47.58/100小時。

2、dumpsys meminfo
在講解dumpsys meminfo命令之前,我們必須先了解下Android中的幾個內存指標的概念:

內存指標 英文全稱 含義 等價
USS Unique Set Size 物理內存 進程獨占的內存
PSS Proportional Set Size 物理內存 PSS = USS + 按比例包含共享庫
RSS Resident Set Size 物理內存 RSS= USS+ 包含共享庫
VSS Virtual Set Size 虛擬內存 VSS= RSS+ 未分配實際物理內存
從上可知,它們之間內存的大小關系為VSS >= RSS >= PSS >= USS。

RSS與PSS相似,也包含進程共享內存,但比較麻煩的是RSS并沒有把共享內存大小全都平分到使用共享的進程頭上,以至于所有進程的RSS相加會超過物理內存很多。而VSS是虛擬地址,它的上限與進程的可訪問地址空間有關,和當前進程的內存使用關系并不大。比如有很多的map內存也被算在其中,我們都知道,file的map內存對應的可能是一個文件或硬盤,或者某個奇怪的設備,它與進程使用內存并沒有多少關系。

而PSS、USS最大的不同在于“共享內存“(比如兩個App使用MMAP方式打開同一個文件,那么打開文件而使用的這部分內存就是共享的),USS不包含進程間共享的內存,而PSS包含。這也造成了USS因為缺少共享內存,所有進程的USS相加要小于物理內存大小的原因。

最早的時候官方就推薦使用PSS曲線圖來衡量App的物理內存占用,而Android 4.4之后才加入USS。但是PSS,有個很大的問題,就是”共享內存“,考慮一種情況,如果A進程與B進程都會使用一個共享SO庫,那么so庫中初始化所用掉的那部分內存就會平分到A與B的頭上。但是A是在B之后啟動的,那么對于B的PSS曲線而言,在A啟動的那一刻,即使B沒有做任何事情,也會出現一個比較大的階梯狀下滑,這會給用曲線圖分析軟件內存的行為造成致命的麻煩。

USS雖然沒有這個問題,但是由于Dalvik虛擬機申請內存牽扯到GC時延和多種GC策略,這些都會影響到曲線的異常波動。比如異步GC是Android 4.0以上系統很重要的特性,但是GC什么時候結束?曲線什么時候”降低“?就無法預計了。還有GC策略,什么時候開始增加Dalvik虛擬機的預申請內幕才能大小(Dalvik啟動時是由一個標稱的start內存大小的,為Java代碼運行時預留,避免Java運行時再申請而造成卡頓),但是這個預申請大小是動態變化的,這一點也會造成USS忽大忽小。

了解完Android內存的性能指標之后,下面我們便來說說dumpsys meminfo這個命令的用法,首先我們輸入adb shell dumpsys meminfo -h查看它的幫助文檔:

quchao@quchaodeMacBook-Pro ~ % adb shell dumpsys meminfo -h
meminfo dump options: [-a] [-d] [-c] [-s] [–oom] [process]
-a: include all available information for each process.
-d: include dalvik details.
-c: dump in a compact machine-parseable representation.
-s: dump only summary of application memory usage.
-S: dump also SwapPss.
–oom: only show processes organized by oom adj.
–local: only collect details locally, don’t call process.
–package: interpret process arg as package, dumping all
processes that have loaded that package.
–checkin: dump data for a checkin
If [process] is specified it can be the name or
pid of a specific process to dump.
接著,我們之間輸入adb shell dumpsys meminfo命令:

quchao@quchaodeMacBook-Pro ~ % adb shell dumpsys meminfo
Applications Memory Usage (in Kilobytes):
Uptime: 257501238 Realtime: 257501238

// 根據進程PSS占用值從大到小排序
Total PSS by process:
308,049K: com.tencent.mm (pid 3760 / activities)
225,081K: system (pid 2088)
189,038K: com.android.systemui (pid 2297 / activities)
188,877K: com.miui.home (pid 2672 / activities)
176,665K: com.plan.kot32.tomatotime (pid 22744 / activities)
175,231K: json.chao.com.wanandroid (pid 23104 / activities)
126,918K: com.tencent.mobileqq (pid 23741)

// 以oom來劃分,會詳細列舉所有的類別的進程
Total PSS by OOM adjustment:
432,013K: Native
76,700K: surfaceflinger (pid 784)
59,084K: android.hardware.camera.provider@2.4-service (pid 743)
26,524K: transport (pid 23418)
25,249K: logd (pid 597)
11,413K: media.codec (pid 1303)
10,648K: rild (pid 1304)
9,283K: media.extractor (pid 1297)

661,294K: Persistent225,081K: system (pid 2088)189,038K: com.android.systemui (pid 2297 / activities)103,050K: com.xiaomi.finddevice (pid 3134)39,098K: com.android.phone (pid 2656)25,583K: com.miui.daemon (pid 3078)...219,795K: Foreground175,231K: json.chao.com.wanandroid (pid 23104 / activities)44,564K: com.miui.securitycenter.remote (pid 2986)246,529K: Visible71,002K: com.sohu.inputmethod.sogou.xiaomi (pid 4820)52,305K: com.miui.miwallpaper (pid 2579)40,982K: com.miui.powerkeeper (pid 3218)24,604K: com.miui.systemAdSolution (pid 7986)14,198K: com.xiaomi.metoknlp (pid 3506)13,820K: com.miui.voiceassist:core (pid 8722)13,222K: com.miui.analytics (pid 8037)7,046K: com.miui.hybrid:entrance (pid 7922)5,104K: com.miui.wmsvc (pid 7887)4,246K: com.android.smspush (pid 8126)213,027K: Perceptible89,780K: com.eg.android.AlipayGphone (pid 8238)49,033K: com.eg.android.AlipayGphone:push (pid 8204)23,181K: com.android.thememanager (pid 11057)13,253K: com.xiaomi.joyose (pid 5558)10,292K: com.android.updater (pid 3488)9,807K: com.lbe.security.miui (pid 23060)9,734K: com.google.android.webview:sandboxed_process0 (pid 11150)7,947K: com.xiaomi.location.fused (pid 3524)308,049K: Backup308,049K: com.tencent.mm (pid 3760 / activities)74,250K: A Services59,701K: com.tencent.mm:push (pid 7234)9,247K: com.android.settings:remote (pid 27053)5,302K: com.xiaomi.drivemode (pid 27009)199,638K: Home188,877K: com.miui.home (pid 2672 / activities)10,761K: com.miui.hybrid (pid 7945)53,934K: B Services35,583K: com.tencent.mobileqq:MSF (pid 14119)6,753K: com.qualcomm.qti.autoregistration (pid 8786)4,086K: com.qualcomm.qti.callenhancement (pid 26958)3,809K: com.qualcomm.qti.StatsPollManager (pid 26993)3,703K: com.qualcomm.qti.smcinvokepkgmgr (pid 26976)692,588K: Cached176,665K: com.plan.kot32.tomatotime (pid 22744 / activities)126,918K: com.tencent.mobileqq (pid 23741)72,928K: com.tencent.mm:tools (pid 18598)68,208K: com.tencent.mm:sandbox (pid 27333)55,270K: com.tencent.mm:toolsmp (pid 18842)24,477K: com.android.mms (pid 27192)23,865K: com.xiaomi.market (pid 27825)...

// 按內存的類別來進行劃分
Total PSS by category:
957,931K: Native
284,006K: Dalvik
199,750K: Unknown
193,236K: .dex mmap
191,521K: .art mmap
110,581K: .oat mmap
101,472K: .so mmap
94,984K: EGL mtrack
87,321K: Dalvik Other
84,924K: Gfx dev
77,300K: GL mtrack
64,963K: .apk mmap
17,112K: Other mmap
12,935K: Ashmem
3,364K: Stack
2,343K: .ttf mmap
1,375K: Other dev
1,071K: .jar mmap
20K: Cursor
0K: Other mtrack

// 手機整體內存使用情況
Total RAM: 5,847,124K (status normal)
Free RAM: 3,711,324K ( 692,588K cached pss + 2,428,616K cached kernel + 117,492K cached ion + 472,628K free)
Used RAM: 2,864,761K (2,408,529K used pss + 456,232K kernel)
Lost RAM: 184,330K
ZRAM: 174,628K physical used for 625,388K in swap (2,621,436K total swap)
Tuning: 256 (large 512), oom 322,560K, restore limit 107,520K (high-end-gfx)
根據dumpsys meminfo的輸出結果,可歸結為如下表格:

劃分類型 排序指標 含義
process PSS 以進程的PSS從大到小依次排序顯示,每行顯示一個進程,一般用來做初步的競品分析
OOM adj PSS 展示當前系統內部運行的所有Android進程的內存狀態和被殺順序,越靠近下方的進程越容易被殺,排序按照一套復雜的算法,算法涵蓋了前后臺、服務或節目、可見與否、老化等
category PSS 以Dalvik/Native/.art mmap/.dex map等劃分并按降序列出各類進程的總PSS分布情況
total - 總內存、剩余內存、可用內存、其他內存
此外,為了查看單個App進程的內存信息,我們可以輸入如下命令:

dumpsys meminfo // 輸出指定pid的某一進程
dumpsys meminfo --package // 輸出指定包名的進程,可能包含多個進程
這里我們輸入adb shell dumpsys meminfo 23104這條命令,其中23104為Awesome-WanAndroid App的pid,結果如下所示:

quchao@quchaodeMacBook-Pro ~ % adb shell dumpsys meminfo 23104
Applications Memory Usage (in Kilobytes):
Uptime: 258375231 Realtime: 258375231

** MEMINFO in pid 23104 [json.chao.com.wanandroid] **
Pss Private Private SwapPss Heap Heap Heap
Total Dirty Clean Dirty Size Alloc Free
------ ------ ------ ------ ------ ------ ------
Native Heap 46674 46620 0 164 80384 60559 19824
Dalvik Heap 6949 6912 16 23 12064 6032 6032
Dalvik Other 7672 7672 0 0
Stack 108 108 0 0
Ashmem 134 132 0 0
Gfx dev 16036 16036 0 0
Other dev 12 0 12 0
.so mmap 3360 228 1084 27
.jar mmap 8 8 0 0
.apk mmap 28279 11328 11584 0
.ttf mmap 295 0 80 0
.dex mmap 7780 20 4908 0
.oat mmap 660 0 92 0
.art mmap 8509 8028 104 69
Other mmap 982 8 848 0
EGL mtrack 29388 29388 0 0
GL mtrack 14864 14864 0 0
Unknown 2532 2500 8 20
TOTAL 174545 143852 18736 303 92448 66591 25856

App Summary
Pss(KB)
------
Java Heap: 15044
Native Heap: 46620
Code: 29332
Stack: 108
Graphics: 60288
Private Other: 11196
System: 11957

TOTAL: 174545 TOTAL SWAP PSS: 303

Objects
Views: 171 ViewRootImpl: 1
AppContexts: 3 Activities: 1
Assets: 18 AssetManagers: 6
Local Binders: 32 Proxy Binders: 27
Parcel memory: 11 Parcel count: 45
Death Recipients: 1 OpenSSL Sockets: 0
WebViews: 0

SQL
MEMORY_USED: 371
PAGECACHE_OVERFLOW: 72 MALLOC_SIZE: 117

DATABASES
pgsz dbsz Lookaside(b) cache Dbname
4 60 109 151/32/18 /data/user/0/json.chao.com.wanandroid/databases/bugly_db_
4 20 19 0/15/1 /data/user/0/json.chao.com.wanandroid/databases/aws_wan_android.db
該命令輸出的進程內存概括,我們應該著重關注幾個點,下面我將進行一一講解。

1、查看Native Heap的Heap Alloc與Dalvik Heap的Heap Alloc
我們可以查看Native Heap的Heap Alloc的數值變化,它表示native的內存占用,如果持續上升,則可能有泄漏,而Dalvik Heap的Heap Alloc則表示Java層的內存占用。

2、查看Views、Activities、AppContexts數量變化情況
如果Views與Activities、AppContexts持續上升,則表明有內存泄漏的風險。

3、SQL的MEMORY_USED與PAGECACHE_OVERFLOW
SQL的MEMOERY_USED表示數據庫使用的內存,而PAGECACHE_OVERFLOW則表示溢出也使用的緩存,這個數值越小越好。

4、查看DATABASES信息
其中pgsz表示數據庫分頁大小,這里全是4KB;Lookaside(b)表示使用了多少個Lookaside的slots,可理解為內存占用的大小;而cache一欄中的 151/32/18 則分別表示分頁緩存命中次數/未命中次數/分頁緩存個數,這里的未命中次數不應該大于命中次數。

3、LeakInspector
LeakInspector是騰訊內部的使用的一站式內存泄漏解決方案,它是Android手機經過長期積累和提煉、集內存泄漏檢測、自動修復系統Bug、自動回收已泄露Activity內資源、自動分析GC鏈、白名單過濾等功能于一體,并深度對接研發流程、自動分析責任人并提缺陷單的全鏈路體系。

那么LeakInspector與LeakCanary又有什么不同呢?
它們之間主要有四個方面的不同:

一、檢測能力與原理方面不同

1、檢測能力

它們都支持對Activity、Fragment及其它自定義類的泄漏檢測,但是LeakInspector還增加了Btiamp的檢測能力:

檢測有沒有在View上decode超過該View尺寸的圖片,若有則上報出現問題的Activity及與其對應的View id,并記錄它的個數與平均占用內存的大小。
檢測圖片尺寸是否超過所有手機屏幕大小,違規則報警。
這一個部分的實現原理,主要是采用ARTHook來實現,還不清楚的朋友請再仔細看看大圖檢測的部分。

2、檢測原理

兩個工具的泄漏檢測原理都是在onDestroy時檢查弱引用,不同之處在于LeakInspector直接使用WeakReference來檢測對象是否已經被釋放,而LeakCanary則使用ReferenceQueue,兩者效果是一樣的。

并且針對Activity,我們通常都會使用Application的registerActivityLifecycleCallbacks來注冊Activity的生命周期,以重寫onActivityDestroyed方法實現。但是在Android 4.0以下,系統并沒有提供這個方法,為了避免手動在每一個Activity的onDestroy中去添加這份代碼,我們可以使用發射Instrumentation來截獲onDestory,以降低接入成本。代碼如下所示:

Class<?> clazz = Class.forName(“android.app.ActivityThread”);
Method method = clazz.getDeclaredMethod(“currentActivityThread”, null);
method.setAccessible(true);
sCurrentActivityThread = method.invoke(null, null);
Field field = sCurrentActivityThread.getClass().getDeclaredField(“mInstumentation”);
field.setAccessible(true);
field.set(sCurrentActivityThread, new MonitorInstumentation());
二、泄漏現場處理方面不同

1、dump采集

兩者都能采集dump,但是LeakInspector提供了回調方法,我們可以增加更多的自定義信息,如運行時Log、trace、dumpsys meminfo等信息,以輔助分析定位問題。

2、白名單定義

這里的白名單是為了處理一些系統引起的泄漏問題,以及一些因為業務邏輯要開后門的情形而設置的。分析時如果碰到白名單上標識的類,則不對這個泄漏做后續的處理。二者的配置差異如下所示:

(1)LeakInspector的白名單以XML配置的形式存放在服務器上。

優點:跟產品甚至不同版本的應用綁定,我們可以很方便地修改相應的配置。
缺點:白名單里的類不區分系統版本一刀切。
而LeakCanary的白名單是直接寫死在其源碼的AndroidExcludedRefs類里。

優點:定義非常詳細,并區分系統版本。
缺點:每次修改必定得重新編譯。
(2)LeakCanary的系統白名單里定義的類比LeakInspector中定義的多很多,因為它沒有自動修復系統泄漏功能。

3、自動修復系統泄漏

針對系統泄漏,LeakInspector通過反射自動修復了目前碰到的一些系統泄漏,只要在onDestory里面調研一個修復系統泄漏的方法即可。而LeakCanary雖然能識別系統泄漏,但是它僅僅對該類問題給出了分析,沒有提供實際可用的解決方案。

4、回收資源

如果檢測到發生了內存泄漏,LeakInspector會對整個Activity的View進行遍歷,把圖片資源等一些占內存的數據釋放掉,保證此次泄漏只會泄漏一個Activity的空殼,盡量減少對內存的影響。代碼大致如下所示:

if (View instanceof ImageView) {
// ImageView ImageButton處理
recycleImageView(app, (ImageView) view);
} else if (view instanceof TextView) {
// 釋放TextView、Button周邊圖片資源
recycleTextView((TextView) view);
} else if (View instanceof ProgressBar) {
recycleProgressBar((ProgressBar) view);
} else {
if (view instancof android.widget.ListView) {
recycleListView((android.widget.ListView) view);
} else if (view instanceof android.support.v7.widget.RecyclerView) {
recycleRecyclerView((android.support.v7.widget.RecyclerView) view);
} else if (view instanceof FrameLayout) {
recycleFrameLayout((FrameLayout) view);
} else if (view instanceof LinearLayout) {
recycleLinearLayout((LinearLayout) view);
}

if (view instanceof ViewGroup) {recycleViewGroup(app, (ViewGroup) view); }

}
這里以recycleTextView為例,它回收資源的方式如下所示:

private static void recycleTextView(TextView tv) {
Drawable[] ds = tv.getCompoundDrawables();
for (Drawable d : ds) {
if (d != null) {
d.setCallback(null);
}
}
tv.setCompoundDrawables(null, null, null, null);
// 取消焦點,讓Editor$Blink這個Runnable不再被post,解決內存泄漏。
tv.setCursorVisible(false);
}
三、后期處理不同

1、分析與展示

采集dump之后,LeakInspector會上傳dump文件,并調用MAT命令行來進行分析,得到這次泄漏的GC鏈;而LeakCanary則用開源組件HAHA來分析得到一個GC鏈。但是LeakCanary得到的GC鏈包含被hold主的類對象,一般都不需要用MAT打開Hporf即可解決問題;而LeakInpsector得到的GC鏈李只有類名,還需要MAT打開Hprof才能具體去定位問題,不是很方便。

2、后續跟進閉環

LeakInspector在dump分析結束之后,會提交缺陷單,并且把缺陷單分配給對應類的負責人;如果發現重復的問題則更新舊單,同時具備重新打開單等狀態轉換羅家。而LeakCanary僅會在通知欄提醒用戶,需要用戶自己記錄該問題并做后續處理。

四、配合自動化測試方面不同

LeakInspector跟自動化測試可以無縫結合,當自動化腳本執行中發現內存泄漏,可以由它采集dump并發送到服務進行分析,最后提單,整個流程是不需要人力介入的。而LeakCanary則把分析結果通過通知欄告知用戶,需要人工介入才能進入下一個流程。

4、JHat
JHat是Oracle推出的一款Hprof分析軟件,它和MAT并稱為Java內存靜態分析利器。不同于MAT的單人界面式分析,jHat使用多人界面式分析。它被內置在JDK中,在命令行中輸入jhat命令可查看沒有有相應的命令。

quchao@quchaodeMacBook-Pro ~ % jhat
ERROR: No arguments supplied
Usage: jhat [-stack ] [-refs ] [-port ] [-baseline ] [-debug ] [-version] [-h|-help]

-J<flag> Pass <flag> directly to the runtime system. Forexample, -J-mx512m to use a maximum heap size of 512MB -stack false: Turn off tracking object allocation call stack. -refs false: Turn off tracking of references to objects -port <port>: Set the port for the HTTP server. Defaults to 7000 -exclude <file>: Specify a file that lists data members that shouldbe excluded from the reachableFrom query. -baseline <file>: Specify a baseline object dump. Objects inboth heap dumps with the same ID and same class willbe marked as not being "new". -debug <int>: Set debug level.0: No debug output1: Debug hprof file parsing2: Debug hprof file parsing, no server -version Report version number -h|-help Print this help and exit <file> The file to read

For a dump file that contains multiple heap dumps,
you may specify which dump in the file
by appending “#” to the file name, i.e. “foo.hprof#3”.
如上,則表明存在jhat命令。它的使用很簡單,直在命令行輸入jhat xxx.hprof即可:

quchao@quchaodeMacBook-Pro ~ % jhat Documents/heapdump/new-33.hprof
Snapshot read, resolving…
Resolving 408200 objects…
Chasing references, expect 81 dots…
Eliminating duplicate references…
Snapshot resolved.
Started HTTP server on port 7000
Server is ready.
jHat的執行過程是解析Hprof文件,然后啟動httpsrv服務,默認是在7000端口監聽Web客戶端鏈接,維護Hprof解析后數據,以持續供給Web客戶端的查詢操作。

啟動服務器后,我們打開入口地址127.0.0.1:7000即可查看All Classes界面:

image

jHat還有兩個比較重要的功能:

1、統計表
打開127.0.0.1:7000/histo/:

image

2、OQL查詢
OQL是一種模仿SQL語句的查詢語句,通常用來查詢某個類的實例數量,打開127.0.0.1:7000/oql/并輸入java.lang.String查詢String實例的數量,如下所示:

image

JHat比MAT更加靈活,且符合大型團隊安裝簡單、團隊協作的需求你,并不適合中小型高效溝通型團隊使用。

5、GC Log
GC Log分為Dalvik和ART的GC日志,關于Dalvik的GC日志,在前篇Android性能優化之內存優化已經詳細講解過了,接下來我們說說ART的GC日志。

ART的日志與Dalvik的日志差距非常大,除了格式不同之外,打印的時間也不同,非要在慢GC時才打印除了。下面我們看看這條ART GC Log:

Explicit (full) concurrent mark sweep GC freed 104710 (7MB) AllocSpace objects, 21(416KB) LOS objects, 33% free,25MB/38MB paused 1.230ms total 67.216ms
GC產生的原因 GC類型 采集方法 釋放的數量和占用的空間 釋放的大對象數量和所占用的空間 堆中空閑空間的百分比和(對象的個數)/(堆的總空間) 暫停耗時
GC產生的原因如下:

Concurrent、Alloc、Explicit跟Dalvik的基本一樣,這里就不重復介紹了。
NativeAlloc:Native內存分配時,比如為Bitmaps或者RenderScript分配對象, 這會導致Native內存壓力,從而觸發GC。
Background:后臺GC,觸發是為了給后面的內存申請預留更多空間。
CollectorTransition:由堆轉換引起的回收,這是運行時切換GC而引起的。收集器轉換包括將所有對象從空閑列表空間復制到碰撞指針空間(反之亦然)。當前,收集器轉換僅在以下情況下出現:在內存較小的設備上,App將進程狀態從可察覺的暫停狀態變更為可察覺的非暫停狀態(反之亦然)。
HomogeneousSpaceCompact:齊性空間壓縮是指空閑列表到壓縮的空閑列表空間,通常發生在當App已經移動到可察覺的暫停進程狀態。這樣做的主要原因是減少了內存使用并對堆內存進行碎片整理。
DisableMovingGc:不是真正的觸發GC原因,發生并發堆壓縮時,由于使用了
GetPrimitiveArrayCritical,收集會被阻塞。一般情況下,強烈建議不要使用
GetPrimitiveArrayCritical,因為它在移動收集器方面具有限制。
HeapTrim:不是觸發GC原因,但是請注意,收集會一直被阻塞,直到堆內存整理完畢。
GC類型如下:

Full:與Dalvik的FULL GC差不多。
Partial:跟Dalvik的局部GC差不多,策略時不包含Zygote Heap。
Sticky:另外一種局部中的局部GC,選擇局部的策略是上次垃圾回收后新分配的對象。
GC采集的方法如下:

mark sweep:先記錄全部對象,然后從GC ROOT開始找出間接和直接的對象并標注。利用之前記錄的全部對象和標注的對象對比,其余的對象就應該需要垃圾回收了。
concurrent mark sweep:使用mark sweep采集器的并發GC。
mark compact:在標記存活對象的時候,所有的存活對象壓縮到內存的一端,而另一端可以更加高效地被回收。
semispace:在做垃圾掃描的時候,把所有引用的對象從一個空間移到另外一個空間,然后直接GC剩余在舊空間中的對象即可。
通過GC日志,我們可以知道GC的量和它對卡頓的影響,也可以初步定位一些如主動調用GC、可分配的內存不足、過多使用Weak Reference等問題。

6、自帶防泄漏功能的線程池組件
我們在做子線程操作的時候,喜歡使用匿名內部類Runnable來操作,但是,如果某個Activity放在線程池中的任務不能及時執行完畢,在Activity銷毀時很容易導致內存泄漏。因為這個匿名內部類Runnable類持有一個指向Outer類的引用,這樣一來如果Activity里面的Runnable不能及時執行,就會使它外圍的Activity無法釋放,產生內存泄漏。從上面的分析可知,只要在Activity退出時沒有這個引用即可,那我們就通過反射,在Runnable進入線程池前先干掉它,代碼如下所示:

Field f = job.getClass().getDeclaredField(“this$0”);
f.setAccessible(true);
f.set(job, null);
這個任務就是我們的Runnable對象,而”this$0“就是上面所指的外部類的引用了。這里注意使用WeakReference裝起來,要執行了先get一下,如果是null則說明Activity已經回收,任務就放棄執行。

7、Chrome Devtool
對于HTML5頁面而言,抓取JavaScript的內存需要使用Chrome Devtools來進行遠程調試。方式有如下兩種:

直接把URL抓取出來放到Chrome里訪問。
用Android H5遠程調試。
純H5
1、手機安裝Chrome,打開USB調試模式,通過USB連上電腦,在Chrome里打開一個頁面,比如百度頁面。然后在PC Chrome地址欄里訪問Chrome://inspect,如下圖所示:

image

2、最后,直接點擊Chrome下面的inspect選項即可彈出開發者工具界面。如下圖所示:

image

默認Hybrid H5調試
Android 4.4及以上系統的原生瀏覽器就是Chrome瀏覽器,可以使用Chrome Devtool遠程調試WebView,前提是需要在App的代碼里把調試開關打開,如下代碼所示:

if (Build.VERSION_SDK_INT >= Build.VERSION_CODES.KITKAT && 是debug模式) {
WebView.setWebContentsDebuggingEnabled(ture);
}
打開后的調試方法跟純H5頁面調試方法一樣,直接在App中打開H5頁面,再到PC Chrome的inpsector頁面就可以看到調試目標頁面。

這里總結一下JS中幾種常見的內存問題點:

closure閉包函數。
事件監聽。
變量作用域使用不當,全局變量的引用導致無法釋放。
DOM節點的泄漏。
若想更深入地學習Chrome開發者工具的使用方法,請查看《Chrome開發者工具中文手冊》。

九、內存問題總結
在我們進行內存優化的過程中,有許多內存問題都可以歸結為一類問題,為了便于以后快速地解決類似的內存問題,我將它們歸結成了以下的多個要點:

1、內類時有危險的編碼方式
說道內類就不得不提到”this$0“,它是一種奇特的內類成員,每個類實例都具有一個this$0,當它的內類需要訪問它的成員時,內類就會持有外類的this$0,通過this$0就可以訪問外部類所有的成員。

解決方案是在Activity關閉時,觸發onDestory時解除內類和外部的引用關系。

2、普通Hanlder內部類的問題
這也是一個this$0間接引用的問題,對于Handler的解決方案一般博阿凱如下三個要點:

1、把內類聲明成static,來斷絕this$0的引用。因為static描述的內類從Java編譯原理的角度看,”內類“與”外類“相互怒獨立,互相都沒有訪問對方成員變量的能力。
2、使用WeakReference來引用外部類的實例。
3、在外部類(如Activity)銷毀的時候使用removeCallbackAndMessages來移除回調和消息。
這里需要在使用過程中注意對WeakReference進行判空。

3、登錄界面的內存問題
如果在閃屏頁跳轉到登錄界面時沒有調用finish(),則會造成閃屏頁的內存泄漏,在碰到這種”過渡界面“的情況時,需要注意不要產生這樣的內存Bug。

4、使用系統服務時產生的內存問題
我們通常都會使用getSystemService方法來獲取系統服務,但是當在Activity中調用時,會默認把Activity的Context傳給系統服務,在某些不確定的情況下,某些系統服務內部會產生異常,從而hold住外界傳入的Context。

解決方案是直接使用Applicaiton的Context去獲取系統服務。

5、把WebView類型的泄漏裝進垃圾桶進程
我們都知道,對應WebView來說,其網絡延時、引擎Session管理、Cookies管理、引擎內核線程、HTML5調用系統聲音、視頻播放組件等產生的引用鏈條無法及時打斷,造成的內存問題基本上可以用”無解“來形容。

解決方案是我們可以把WebView裝入另一個進程。
在AndroidManifest中對當前的Activity設置android:process屬性即可,最后再Activity的onDestory中退出進程,這樣即可基本上終結WebView造成的泄漏。

6、在適當的時候對組件進行注銷
我們在平常開發過程中經常需要在Activity創建的時候去注冊一些組件,如廣播、定時器、事件總線等等。這個時候我們應該在適當的時候對組件進行注銷,如onPause或onDestory方法中。

7、Handler/FrameLayout的postDelyed方法觸發的內存問題
不僅在使用Handler的sendMessage方法時,我們需要在onDestory中使用removeCallbackAndMessage移除回調和消息,在使用到Handlerh/FrameLayout的postDelyed方法時,我們需要調用removeCallbacks去移除實現控件內部的延時器對Runnable內類的持有。

8、圖片放錯資源目錄也會有內存問題
在做資源適配的時候,因為需要考慮到APK的瘦身問題,無法為每張圖片在每個drawable/mipmap目錄下安置一張適配圖片的副本。很多同學不知道圖片應該放哪個目錄,如果放到分辨率低的目錄如hdpi目錄,則可能會造成內存問題,這個時候建議盡量問設計人員要高品質圖片然后往高密度目錄下方,如xxhdpi目錄,這樣在低密屏上”放大倍數“是小于1的,在保證畫質的前提下,內存也是可控的。也可以使用Drawable.createFromSream替換getResources().getDrawable來加載,這樣便可以繞過Android的默認適配規則。

對于已經被用戶使用物理“返回鍵”退回到后臺的進程,如果包含了以下幾點,則不會被輕易殺死。

進程包含了服務startService,而服務本身調用了startForeground(需通過反射調用)。
主Activity沒有實現onSaveInstanceState接口。
但建議在運行一段時間(如3小時)后主動保存界面進程,然后重啟它,這樣可以有效地降低內存負載。

十、內存優化常見問題
1、你們內存優化項目的過程是怎么做的?
1、分析現狀、確認問題
我們發現我們的APP在內存方面可能存在很大的問題,第一方面的原因是我們的線上的OOM率比較高。第二點呢,我們經常會看到在我們的Android Studio的Profiler工具中內存的抖動比較頻繁。這是我一個初步的現狀,然后在我們知道了這個初步的現狀之后,進行了問題的確認,我們經過一系列的調研以及深入研究,我們最終發現我們的項目中存在以下幾點大問題,比如說:內存抖動、內存溢出、內存泄漏,還有我們的Bitmap使用非常粗獷。

2、針對性優化
比如內存抖動的解決 -> Memory Profiler工具的使用(呈現了鋸齒張圖形) -> 分析到具體代碼存在的問題(頻繁被調用的方法中出現了日志字符串的拼接),也可以說說內存泄漏或內存溢出的解決。

3、效率提升
為了不增加業務同學的工作量,我們使用了一些工具類或ARTHook這樣的大圖檢測方案,沒有任何的侵入性,同時,我們將這些技術教給了大家,然后讓大家一起進行工作效率上的提升。

我們對內存優化工具Memory Profiler、MAT的使用比較熟悉,因此針對一系列不同問題的情況,我們寫了一系列解決方案的文檔,分享給大家。這樣,我們整個團隊成員的內存優化意識就變強了。

2、你做了內存優化最大的感受是什么?
1、磨刀不誤砍柴工
我們一開始并沒有直接去分析項目中代碼哪些地方存在內存問題,而是先去學習了Google官方的一些文檔,比如說學習了Memory Profiler工具的使用、學習了MAT工具的使用,在我們將這些工具學習熟練之后,當在我們的項目中遇到內存問題時,我們就能夠很快地進行排查定位問題進行解決。

2、技術優化必須結合業務代碼
一開始,我們做了整體APP運行階段的一個內存上報,然后,我們在一些重點的內存消耗模塊進行了一些監控,但是后面發現這些監控并沒有緊密地結合我們的業務代碼,比如說在梳理完項目之后,發現我們項目中存在使用多個圖片庫的情況,多個圖片庫的內存緩存肯定是不公用的,所以導致我們整個項目的內存使用量非常高。所以進行技術優化時必須結合我們的業務代碼。

3、系統化完善解決方案
我們在做內存優化的過程中,不僅做了Android端的優化工作,還將我們Android端一些數據的采集上報到了我們的服務器,然后傳到我們的后臺,這樣,方便我們的無論是Bug跟蹤人員或者是Crash跟蹤人員進行一系列問題的解決。

3、如何檢測所有不合理的地方?
比如說大圖片的檢測,我們最初的一個方案是通過繼承ImageView,重寫它的onDraw方法來實現。但是,我們在推廣它的過程中,發現很多開發人員并不接受,因為很多ImageView之前已經寫過了,你現在讓他去替換,工作成本是比較高的。所以說,后來我們就想,有沒有一種方案可以免替換,最終我們就找到了ARTHook這樣一個Hook的方案。

十一、總結
對于內存優化的專項優化而言,我們要著重注意兩點,即優化大方向和優化細節。

對于優化的大方向,我們應該優先去做見效快的地方,主要有以下三部分:

1、內存泄漏
2、內存抖動
3、Bitmap
對于優化細節,我們應該注意一些系統屬性或內存回調的使用等等,如下:

1、LargeHeap屬性
2、onTrimMemory
3、使用優化過后的集合:如SparseArray
4、謹慎使用SharedPreference
5、謹慎使用外部庫
6、業務架構設計合理
在本篇文章,我們除了建立了內存的監控閉環這一核心體系之外,還是實現了以下組件:

1、實現了線下的native內存泄漏監控。
2、根據設備分級來使用不同的內存和分配回收策略。
3、針對低端機做了功能或圖片加載格式的降級處理。
4、針對緩存濫用的問題實現了統一的緩存管理組件。
5、實現了大圖監控和重復圖片的監控。
6、在前臺每隔一定時間去獲取當前應用內存占最大內存的比例,當超過設定閾值時則主動釋放應用cache。
7、當UI隱藏時釋放內存以增加系統緩存應用進程的能力。
8、高效實現了應用全局內的Bitmap監控。
9、實現了全局的線程監控
10、針對內存使用的重度場景實現了GC監控。
最后,當監控到應用內存超過閾值時,還定制了完善的兜底策略來重啟應用進程。

從性能分類的緯度來看,除了內存監控方面外,是否也同樣建立了卡頓、緩存、電量、異常流量、布局、包體積、IO、存儲相關的監控與優化體系。總的來說,要想實現更健全的功能、更深層次的定位問題、線上問題快速準確的發現,還是有很多事情可以做的。

路漫漫其修遠兮,吾將上下而求索。
參考鏈接:
1、國內Top團隊大牛帶你玩轉Android性能分析與優化 第四章 內存優化

2、極客時間之Android開發高手課 內存優化

3、微信 Android 終端內存優化實踐

4、GMTC-Android內存泄漏自動化鏈路分析組件Probe.key

5、Manage your app’s memory

6、Overview of memory management

7、Android內存優化雜談

8、Android性能優化之內存篇

9、管理應用的內存

10、《Android移動性能實戰》第二章 內存

11、每天一個linux命令(44):top命令

12、Android內存分析命令

總結

以上是生活随笔為你收集整理的深入探索Android内存优化的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

色婷婷综合激情综在线播放 | 亚洲 日韩 欧美 成人 在线观看 | 国产精品久久久久7777 | 国产 浪潮av性色四虎 | 国模大胆一区二区三区 | 亚洲国产精品成人久久蜜臀 | 国产午夜无码精品免费看 | 日韩欧美群交p片內射中文 | 狠狠躁日日躁夜夜躁2020 | 国产精品亚洲专区无码不卡 | 中文无码伦av中文字幕 | 人妻天天爽夜夜爽一区二区 | 鲁大师影院在线观看 | 麻豆蜜桃av蜜臀av色欲av | 欧美freesex黑人又粗又大 | 国产免费无码一区二区视频 | 亚洲精品久久久久久一区二区 | 亚洲精品中文字幕久久久久 | 性欧美熟妇videofreesex | 人妻尝试又大又粗久久 | 国产精品-区区久久久狼 | 奇米影视888欧美在线观看 | 九九综合va免费看 | www一区二区www免费 | 青青久在线视频免费观看 | 国产精品无码一区二区三区不卡 | 亚洲阿v天堂在线 | 亚洲va中文字幕无码久久不卡 | 蜜臀av在线观看 在线欧美精品一区二区三区 | 99久久亚洲精品无码毛片 | 成人试看120秒体验区 | 成熟妇人a片免费看网站 | 伊人久久大香线蕉午夜 | 亚洲国产精品久久人人爱 | 四虎永久在线精品免费网址 | 亚洲人成影院在线观看 | 日本一卡2卡3卡四卡精品网站 | 99re在线播放 | 日韩人妻无码一区二区三区久久99 | 美女毛片一区二区三区四区 | 色妞www精品免费视频 | 麻豆国产人妻欲求不满 | 日韩人妻少妇一区二区三区 | 国产肉丝袜在线观看 | 国产精华av午夜在线观看 | 噜噜噜亚洲色成人网站 | 亚洲va欧美va天堂v国产综合 | 日本丰满护士爆乳xxxx | 蜜桃无码一区二区三区 | 久久久久久九九精品久 | 中文字幕无码日韩专区 | 中文字幕无码av波多野吉衣 | 美女黄网站人色视频免费国产 | 天天摸天天碰天天添 | 丝袜人妻一区二区三区 | 中国女人内谢69xxxxxa片 | 国产精品-区区久久久狼 | 精品无码一区二区三区的天堂 | 最新版天堂资源中文官网 | 人妻夜夜爽天天爽三区 | 久久国产精品偷任你爽任你 | 亚洲日韩中文字幕在线播放 | 国产亚洲精品久久久久久久久动漫 | 亚洲一区二区三区在线观看网站 | 久久无码中文字幕免费影院蜜桃 | 少妇人妻偷人精品无码视频 | 77777熟女视频在线观看 а天堂中文在线官网 | 国产凸凹视频一区二区 | 亚洲综合久久一区二区 | 国产又爽又猛又粗的视频a片 | 无码免费一区二区三区 | 国产成人午夜福利在线播放 | 成人无码精品1区2区3区免费看 | 国产精品视频免费播放 | 少妇人妻大乳在线视频 | 男女超爽视频免费播放 | 一区二区三区高清视频一 | 日本一区二区三区免费高清 | 日日摸日日碰夜夜爽av | 三级4级全黄60分钟 | 亚洲成av人综合在线观看 | 人人妻人人澡人人爽欧美精品 | 精品欧洲av无码一区二区三区 | 无码国产激情在线观看 | 久久久国产精品无码免费专区 | 亚洲综合伊人久久大杳蕉 | 无码人妻黑人中文字幕 | 国产成人无码午夜视频在线观看 | 蜜桃av抽搐高潮一区二区 | 老熟妇乱子伦牲交视频 | aⅴ在线视频男人的天堂 | 国产成人无码av在线影院 | 无码人妻久久一区二区三区不卡 | 国产精品多人p群无码 | 3d动漫精品啪啪一区二区中 | 久久99久久99精品中文字幕 | 人妻尝试又大又粗久久 | 国产精品成人av在线观看 | 亚洲一区二区三区国产精华液 | 超碰97人人做人人爱少妇 | 成人精品视频一区二区三区尤物 | 亚洲一区二区观看播放 | 乌克兰少妇xxxx做受 | 欧美一区二区三区视频在线观看 | 天天综合网天天综合色 | 日本在线高清不卡免费播放 | 国产区女主播在线观看 | 亚洲精品久久久久中文第一幕 | 国产办公室秘书无码精品99 | 伊人色综合久久天天小片 | 久久亚洲中文字幕无码 | 国产无遮挡又黄又爽又色 | 精品国偷自产在线 | 久久久久久久久蜜桃 | 成人精品天堂一区二区三区 | 日产国产精品亚洲系列 | 亚洲一区二区三区国产精华液 | 国内精品人妻无码久久久影院 | 欧美xxxx黑人又粗又长 | 亚洲欧美国产精品专区久久 | 国产精品久久国产三级国 | 亚洲爆乳无码专区 | 日欧一片内射va在线影院 | 欧美日韩精品 | 两性色午夜视频免费播放 | 亚洲综合伊人久久大杳蕉 | 好男人www社区 | 久热国产vs视频在线观看 | 国产精品久久久久久久影院 | 蜜桃av蜜臀av色欲av麻 999久久久国产精品消防器材 | 无码精品人妻一区二区三区av | 97色伦图片97综合影院 | 日本爽爽爽爽爽爽在线观看免 | 国产电影无码午夜在线播放 | 久久 国产 尿 小便 嘘嘘 | 日本一卡二卡不卡视频查询 | 国产人妻精品午夜福利免费 | 日本在线高清不卡免费播放 | 久久久久久久久蜜桃 | 97无码免费人妻超级碰碰夜夜 | 国产成人综合美国十次 | 好男人社区资源 | 红桃av一区二区三区在线无码av | 色偷偷人人澡人人爽人人模 | 欧美日韩一区二区三区自拍 | 国产xxx69麻豆国语对白 | 国产无遮挡又黄又爽免费视频 | 亚洲中文字幕无码一久久区 | 天天综合网天天综合色 | 欧美第一黄网免费网站 | 中文字幕 亚洲精品 第1页 | а√资源新版在线天堂 | 国产午夜无码视频在线观看 | 亚洲最大成人网站 | 久久亚洲中文字幕精品一区 | 女人被爽到呻吟gif动态图视看 | 久久久精品国产sm最大网站 | 丁香花在线影院观看在线播放 | 人人超人人超碰超国产 | 国产精品久久久 | 日产精品高潮呻吟av久久 | 亚洲人成人无码网www国产 | 久9re热视频这里只有精品 | 97精品人妻一区二区三区香蕉 | 天天做天天爱天天爽综合网 | 精品无码成人片一区二区98 | 四虎4hu永久免费 | 精品国产精品久久一区免费式 | 免费国产成人高清在线观看网站 | 国产成人综合在线女婷五月99播放 | 久久99精品国产.久久久久 | 亚洲人成无码网www | 蜜臀av无码人妻精品 | 婷婷五月综合缴情在线视频 | 天天摸天天透天天添 | 波多野结衣aⅴ在线 | 国产午夜亚洲精品不卡下载 | 久久人人爽人人人人片 | 7777奇米四色成人眼影 | 久久99精品久久久久婷婷 | 日韩人妻无码一区二区三区久久99 | 亚洲娇小与黑人巨大交 | 成 人影片 免费观看 | 久久99精品国产麻豆蜜芽 | 亚洲欧美日韩成人高清在线一区 | 少妇被黑人到高潮喷出白浆 | 人人妻人人藻人人爽欧美一区 | 亚洲国产精品无码一区二区三区 | 午夜精品久久久内射近拍高清 | 中文字幕乱码亚洲无线三区 | 国产激情艳情在线看视频 | 黑人大群体交免费视频 | 激情亚洲一区国产精品 | 欧美成人午夜精品久久久 | 亚洲精品一区二区三区四区五区 | 特大黑人娇小亚洲女 | 色老头在线一区二区三区 | 国精品人妻无码一区二区三区蜜柚 | 嫩b人妻精品一区二区三区 | 中文字幕av伊人av无码av | 西西人体www44rt大胆高清 | 夫妻免费无码v看片 | 丰满岳乱妇在线观看中字无码 | 性史性农村dvd毛片 | 亚洲精品欧美二区三区中文字幕 | 少妇厨房愉情理9仑片视频 | 黑人大群体交免费视频 | 一区二区三区乱码在线 | 欧洲 | 国产午夜亚洲精品不卡 | 97久久国产亚洲精品超碰热 | 男女爱爱好爽视频免费看 | 九九久久精品国产免费看小说 | 强辱丰满人妻hd中文字幕 | 国产9 9在线 | 中文 | 国产熟女一区二区三区四区五区 | 成人欧美一区二区三区黑人免费 | 蜜臀av无码人妻精品 | 国产精品igao视频网 | 日日噜噜噜噜夜夜爽亚洲精品 | 日本一卡2卡3卡4卡无卡免费网站 国产一区二区三区影院 | 国产无遮挡又黄又爽免费视频 | 思思久久99热只有频精品66 | 精品国产一区av天美传媒 | 欧美日韩人成综合在线播放 | 国产成人一区二区三区别 | 中文字幕无码视频专区 | 国产人成高清在线视频99最全资源 | 国产sm调教视频在线观看 | 国产激情一区二区三区 | 福利一区二区三区视频在线观看 | 免费国产成人高清在线观看网站 | 欧美兽交xxxx×视频 | 国产疯狂伦交大片 | 国产莉萝无码av在线播放 | 国语精品一区二区三区 | 久久国产精品_国产精品 | 麻豆md0077饥渴少妇 | 日韩av无码一区二区三区不卡 | 中文字幕av伊人av无码av | 国内精品久久毛片一区二区 | 少妇太爽了在线观看 | 久久aⅴ免费观看 | 国产亚洲精品精品国产亚洲综合 | 国产亚洲美女精品久久久2020 | 熟女体下毛毛黑森林 | 性欧美熟妇videofreesex | 亚洲国产高清在线观看视频 | 久久国产精品精品国产色婷婷 | 亚洲中文无码av永久不收费 | 午夜福利不卡在线视频 | 欧美一区二区三区视频在线观看 | 欧美丰满熟妇xxxx性ppx人交 | 日日摸天天摸爽爽狠狠97 | 久久久精品成人免费观看 | 亚洲gv猛男gv无码男同 | 色婷婷av一区二区三区之红樱桃 | 欧美激情一区二区三区成人 | 国产成人精品三级麻豆 | 男女下面进入的视频免费午夜 | 亚洲乱码国产乱码精品精 | 日产精品99久久久久久 | 色婷婷av一区二区三区之红樱桃 | 久久久久久久女国产乱让韩 | 亚洲欧美综合区丁香五月小说 | 中文字幕无线码免费人妻 | 欧美自拍另类欧美综合图片区 | 爆乳一区二区三区无码 | 日本丰满熟妇videos | 俄罗斯老熟妇色xxxx | 成人欧美一区二区三区 | 对白脏话肉麻粗话av | 超碰97人人做人人爱少妇 | 精品国产精品久久一区免费式 | 日韩欧美中文字幕在线三区 | 国产精品爱久久久久久久 | 国产精品无码久久av | 亚洲精品鲁一鲁一区二区三区 | 日本va欧美va欧美va精品 | 亚洲日韩精品欧美一区二区 | 色婷婷欧美在线播放内射 | 亚洲国产精品久久久久久 | 秋霞特色aa大片 | 男人的天堂av网站 | 精品欧洲av无码一区二区三区 | aa片在线观看视频在线播放 | 无码人妻精品一区二区三区下载 | 人妻无码αv中文字幕久久琪琪布 | 国产精品毛片一区二区 | 最新国产乱人伦偷精品免费网站 | 欧美人与动性行为视频 | 黑人粗大猛烈进出高潮视频 | 成人无码精品1区2区3区免费看 | 精品国产一区二区三区av 性色 | 俺去俺来也在线www色官网 | 熟女俱乐部五十路六十路av | 曰韩少妇内射免费播放 | 九九热爱视频精品 | 乱中年女人伦av三区 | 熟妇人妻无乱码中文字幕 | 欧美三级不卡在线观看 | 国产9 9在线 | 中文 | 亚洲中文字幕va福利 | 国产97人人超碰caoprom | 亚洲国产精品一区二区美利坚 | 久久精品女人天堂av免费观看 | 国产超级va在线观看视频 | 大肉大捧一进一出好爽视频 | 国产xxx69麻豆国语对白 | 久热国产vs视频在线观看 | av无码久久久久不卡免费网站 | 女人被男人躁得好爽免费视频 | 中文字幕中文有码在线 | 国产精品免费大片 | 欧美日本免费一区二区三区 | 国产亚洲精品精品国产亚洲综合 | 最近中文2019字幕第二页 | 在线精品国产一区二区三区 | 中文字幕无码免费久久9一区9 | 国产福利视频一区二区 | 夜夜高潮次次欢爽av女 | 久久精品国产99久久6动漫 | 日韩成人一区二区三区在线观看 | 日韩精品成人一区二区三区 | 亚洲中文字幕在线无码一区二区 | 国产高清av在线播放 | 丰满肥臀大屁股熟妇激情视频 | 久久综合香蕉国产蜜臀av | 国产国产精品人在线视 | 国产精品久久久久久亚洲影视内衣 | 性色欲情网站iwww九文堂 | 东北女人啪啪对白 | 国产免费观看黄av片 | 国产激情无码一区二区 | 麻豆av传媒蜜桃天美传媒 | 欧美熟妇另类久久久久久不卡 | 中文字幕无码热在线视频 | 一本久久伊人热热精品中文字幕 | 亚洲爆乳精品无码一区二区三区 | 中文字幕乱码人妻二区三区 | 国产熟妇高潮叫床视频播放 | 国产熟女一区二区三区四区五区 | 欧美一区二区三区视频在线观看 | 亚洲一区二区三区国产精华液 | 国产9 9在线 | 中文 | 国产精品香蕉在线观看 | 久久精品国产一区二区三区肥胖 | 亚洲欧美日韩国产精品一区二区 | 国内精品人妻无码久久久影院蜜桃 | 99久久精品日本一区二区免费 | 亚洲国产欧美国产综合一区 | 亚洲 欧美 激情 小说 另类 | 亚洲自偷自偷在线制服 | 熟妇人妻无码xxx视频 | 乱人伦人妻中文字幕无码 | 少妇高潮喷潮久久久影院 | 白嫩日本少妇做爰 | 久久久婷婷五月亚洲97号色 | 日本熟妇浓毛 | 欧美日韩亚洲国产精品 | 丰满护士巨好爽好大乳 | 精品一二三区久久aaa片 | 亚洲日韩av一区二区三区四区 | 未满小14洗澡无码视频网站 | 久久精品国产99久久6动漫 | 亚洲中文字幕无码一久久区 | 鲁一鲁av2019在线 | 国产免费无码一区二区视频 | 日本又色又爽又黄的a片18禁 | 亚洲精品鲁一鲁一区二区三区 | 女人被男人躁得好爽免费视频 | 少妇人妻偷人精品无码视频 | 国产av无码专区亚洲awww | 一二三四社区在线中文视频 | 精品国产成人一区二区三区 | 国产精品第一区揄拍无码 | 亚洲最大成人网站 | 亚洲精品欧美二区三区中文字幕 | 中文无码精品a∨在线观看不卡 | 午夜熟女插插xx免费视频 | 欧美精品无码一区二区三区 | 亚洲精品欧美二区三区中文字幕 | 国产婷婷色一区二区三区在线 | 丰腴饱满的极品熟妇 | 成人三级无码视频在线观看 | 无码中文字幕色专区 | 久久久久久九九精品久 | 国产成人精品久久亚洲高清不卡 | 国产午夜福利亚洲第一 | 久久久久亚洲精品男人的天堂 | 丰满人妻被黑人猛烈进入 | 在线播放免费人成毛片乱码 | 一二三四社区在线中文视频 | 激情综合激情五月俺也去 | 领导边摸边吃奶边做爽在线观看 | 亚洲午夜无码久久 | 无码人妻黑人中文字幕 | 国产精品美女久久久 | 内射欧美老妇wbb | 99久久99久久免费精品蜜桃 | 99精品国产综合久久久久五月天 | 波多野结衣一区二区三区av免费 | 亚洲s色大片在线观看 | 国产xxx69麻豆国语对白 | 成熟人妻av无码专区 | 日本精品人妻无码77777 天堂一区人妻无码 | 久久精品国产一区二区三区 | 国产一区二区三区影院 | 亚洲精品综合一区二区三区在线 | 久久久成人毛片无码 | 熟妇人妻无码xxx视频 | 高清无码午夜福利视频 | 国产精品福利视频导航 | 岛国片人妻三上悠亚 | 亚洲 欧美 激情 小说 另类 | 国内精品人妻无码久久久影院蜜桃 | 国产明星裸体无码xxxx视频 | av在线亚洲欧洲日产一区二区 | 亚洲国产精品无码一区二区三区 | 东京热一精品无码av | 少妇太爽了在线观看 | 纯爱无遮挡h肉动漫在线播放 | 精品无码一区二区三区的天堂 | 99国产欧美久久久精品 | 色偷偷av老熟女 久久精品人妻少妇一区二区三区 | 国产无套粉嫩白浆在线 | 人人爽人人澡人人高潮 | 中文字幕久久久久人妻 | 免费国产成人高清在线观看网站 | 成人免费视频在线观看 | 又紧又大又爽精品一区二区 | 最新版天堂资源中文官网 | 久久久av男人的天堂 | 亚洲精品无码人妻无码 | 99riav国产精品视频 | 久久综合网欧美色妞网 | 亲嘴扒胸摸屁股激烈网站 | 青青草原综合久久大伊人精品 | 午夜精品久久久久久久久 | 久久久av男人的天堂 | 精品无码成人片一区二区98 | 天堂在线观看www | 精品一区二区三区无码免费视频 | 特大黑人娇小亚洲女 | 色狠狠av一区二区三区 | 国产精品爱久久久久久久 | 成人综合网亚洲伊人 | 久久国产精品_国产精品 | 青青久在线视频免费观看 | 窝窝午夜理论片影院 | 欧美精品免费观看二区 | av无码久久久久不卡免费网站 | 欧美兽交xxxx×视频 | 精品国产一区二区三区av 性色 | 日本一卡2卡3卡4卡无卡免费网站 国产一区二区三区影院 | 无码任你躁久久久久久久 | 久久精品中文闷骚内射 | 玩弄中年熟妇正在播放 | 国产一区二区不卡老阿姨 | 久久视频在线观看精品 | 永久黄网站色视频免费直播 | 捆绑白丝粉色jk震动捧喷白浆 | 人人爽人人澡人人人妻 | 国产九九九九九九九a片 | 亚洲日韩av一区二区三区四区 | 国产又粗又硬又大爽黄老大爷视 | 亚洲春色在线视频 | 日韩精品成人一区二区三区 | 久久久精品成人免费观看 | 国产无av码在线观看 | 久久99热只有频精品8 | 免费观看激色视频网站 | 久久国产精品精品国产色婷婷 | 国产一区二区三区影院 | 国产舌乚八伦偷品w中 | 国产精品丝袜黑色高跟鞋 | 国产精品沙发午睡系列 | 少妇无码一区二区二三区 | 精品一区二区三区无码免费视频 | 2019nv天堂香蕉在线观看 | 国产麻豆精品精东影业av网站 | 欧美成人高清在线播放 | 综合人妻久久一区二区精品 | 色五月五月丁香亚洲综合网 | 在线播放无码字幕亚洲 | 国产精品久久久一区二区三区 | 国产精品二区一区二区aⅴ污介绍 | 无码福利日韩神码福利片 | 国产凸凹视频一区二区 | 久久精品国产一区二区三区 | 少妇性荡欲午夜性开放视频剧场 | 西西人体www44rt大胆高清 | 人人妻人人澡人人爽精品欧美 | 成年女人永久免费看片 | 亚洲日韩乱码中文无码蜜桃臀网站 | 国产成人精品久久亚洲高清不卡 | 欧美人与物videos另类 | 欧美三级不卡在线观看 | 天海翼激烈高潮到腰振不止 | 国产肉丝袜在线观看 | 7777奇米四色成人眼影 | 性欧美牲交xxxxx视频 | 国产精品手机免费 | 亚洲一区二区三区国产精华液 | 国产成人无码av片在线观看不卡 | 精品久久久无码人妻字幂 | 久久精品99久久香蕉国产色戒 | 国产精品无码成人午夜电影 | www国产精品内射老师 | 老太婆性杂交欧美肥老太 | 亚洲精品中文字幕 | 免费人成网站视频在线观看 | 国产xxx69麻豆国语对白 | 久久精品国产99久久6动漫 | 男女超爽视频免费播放 | 国内老熟妇对白xxxxhd | aa片在线观看视频在线播放 | 人妻有码中文字幕在线 | 亚洲综合伊人久久大杳蕉 | 天下第一社区视频www日本 | 国产乱人无码伦av在线a | 亚洲 a v无 码免 费 成 人 a v | 亚洲成a人片在线观看无码 | 人妻少妇精品久久 | 国产无av码在线观看 | 无套内谢的新婚少妇国语播放 | 综合激情五月综合激情五月激情1 | 精品欧美一区二区三区久久久 | 亚洲欧美色中文字幕在线 | 欧美黑人乱大交 | 高潮毛片无遮挡高清免费 | 精品久久8x国产免费观看 | 国产成人精品优优av | 久久人人97超碰a片精品 | 377p欧洲日本亚洲大胆 | 18禁黄网站男男禁片免费观看 | 日本丰满熟妇videos | 精品欧洲av无码一区二区三区 | 狂野欧美性猛交免费视频 | 久久久亚洲欧洲日产国码αv | 精品国产一区二区三区四区在线看 | 强开小婷嫩苞又嫩又紧视频 | 午夜时刻免费入口 | 久久人人爽人人人人片 | 免费人成在线观看网站 | 国产真人无遮挡作爱免费视频 | 欧洲欧美人成视频在线 | 久久人人爽人人人人片 | 玩弄中年熟妇正在播放 | 国产乱子伦视频在线播放 | 99久久久无码国产aaa精品 | 色欲人妻aaaaaaa无码 | 日韩av无码一区二区三区不卡 | 风流少妇按摩来高潮 | 久久成人a毛片免费观看网站 | 99精品国产综合久久久久五月天 | 亚洲男人av天堂午夜在 | 色综合视频一区二区三区 | 国产av一区二区精品久久凹凸 | 大肉大捧一进一出视频出来呀 | 午夜丰满少妇性开放视频 | 少妇无码av无码专区在线观看 | 国产精品二区一区二区aⅴ污介绍 | 国产人妻精品午夜福利免费 | 少妇人妻av毛片在线看 | 久久亚洲a片com人成 | 精品久久久久久人妻无码中文字幕 | 久久国语露脸国产精品电影 | 亚洲精品中文字幕久久久久 | 成熟妇人a片免费看网站 | 亚洲国产精品无码久久久久高潮 | 亚洲国产高清在线观看视频 | 亚洲日本va午夜在线电影 | 免费人成在线观看网站 | 久久视频在线观看精品 | 日本爽爽爽爽爽爽在线观看免 | 午夜精品久久久久久久 | 中文字幕中文有码在线 | 亚洲国产欧美国产综合一区 | 人人爽人人爽人人片av亚洲 | 十八禁视频网站在线观看 | 3d动漫精品啪啪一区二区中 | 亚洲日韩一区二区 | 精品国产av色一区二区深夜久久 | 国产成人无码a区在线观看视频app | 亚洲一区二区三区播放 | 欧美日韩一区二区三区自拍 | 狂野欧美性猛交免费视频 | 色欲久久久天天天综合网精品 | 亚洲精品国产精品乱码不卡 | 成人三级无码视频在线观看 | 精品无码av一区二区三区 | 国产精品久久国产精品99 | 国产亚洲精品久久久久久久久动漫 | 免费网站看v片在线18禁无码 | 亚洲综合无码一区二区三区 | 无码人妻久久一区二区三区不卡 | 亚洲性无码av中文字幕 | 丰满妇女强制高潮18xxxx | 欧洲熟妇色 欧美 | 无码av免费一区二区三区试看 | 少妇的肉体aa片免费 | 欧美人与禽zoz0性伦交 | 日本va欧美va欧美va精品 | 午夜不卡av免费 一本久久a久久精品vr综合 | 欧美第一黄网免费网站 | 学生妹亚洲一区二区 | 亚洲 日韩 欧美 成人 在线观看 | 国产人妻人伦精品1国产丝袜 | 无码人妻少妇伦在线电影 | 中文字幕亚洲情99在线 | 亚洲欧美日韩成人高清在线一区 | 亚洲一区二区观看播放 | 国产午夜精品一区二区三区嫩草 | 六月丁香婷婷色狠狠久久 | 亚洲中文字幕成人无码 | 亚洲色www成人永久网址 | 欧美日韩人成综合在线播放 | 亚洲成色在线综合网站 | 欧美人与禽zoz0性伦交 | 久久99精品久久久久久动态图 | 丰腴饱满的极品熟妇 | 少妇人妻大乳在线视频 | 日本精品少妇一区二区三区 | 亚洲va欧美va天堂v国产综合 | 少妇性l交大片欧洲热妇乱xxx | 久久99精品国产麻豆蜜芽 | 欧美日韩色另类综合 | 成人性做爰aaa片免费看 | 男女爱爱好爽视频免费看 | 亚洲欧洲日本无在线码 | 亚洲乱码日产精品bd | 秋霞成人午夜鲁丝一区二区三区 | 亚洲一区av无码专区在线观看 | 少妇高潮一区二区三区99 | 九九热爱视频精品 | 亚洲精品一区二区三区在线 | 精品无码国产一区二区三区av | 成人欧美一区二区三区黑人免费 | 一本精品99久久精品77 | 亚拍精品一区二区三区探花 | 久久无码人妻影院 | 欧美国产日韩亚洲中文 | 装睡被陌生人摸出水好爽 | 宝宝好涨水快流出来免费视频 | 久久人人爽人人爽人人片ⅴ | 成人片黄网站色大片免费观看 | 国产偷国产偷精品高清尤物 | 黑人大群体交免费视频 | 少妇人妻av毛片在线看 | 人妻无码αv中文字幕久久琪琪布 | 一个人看的www免费视频在线观看 | 成在人线av无码免费 | 国产亚av手机在线观看 | 久久久久亚洲精品中文字幕 | 欧美人与禽zoz0性伦交 | 亚洲狠狠婷婷综合久久 | 日日鲁鲁鲁夜夜爽爽狠狠 | 少妇无套内谢久久久久 | 亚洲人成网站免费播放 | 国产女主播喷水视频在线观看 | 久久国产精品二国产精品 | 色婷婷欧美在线播放内射 | 疯狂三人交性欧美 | 精品久久久中文字幕人妻 | 黑人巨大精品欧美一区二区 | 宝宝好涨水快流出来免费视频 | 国产精品高潮呻吟av久久 | 亚洲成av人综合在线观看 | 成人精品一区二区三区中文字幕 | 一本久道久久综合狠狠爱 | 少妇被黑人到高潮喷出白浆 | 东京热无码av男人的天堂 | 成人性做爰aaa片免费看不忠 | 色婷婷综合中文久久一本 | 理论片87福利理论电影 | 亚洲欧洲日本无在线码 | 中文字幕乱码亚洲无线三区 | 亚洲一区二区观看播放 | 国产黄在线观看免费观看不卡 | 色婷婷综合中文久久一本 | 图片区 小说区 区 亚洲五月 | 人妻无码αv中文字幕久久琪琪布 | 国产xxx69麻豆国语对白 | 国产超碰人人爽人人做人人添 | 日本一卡2卡3卡四卡精品网站 | 天海翼激烈高潮到腰振不止 | 夜精品a片一区二区三区无码白浆 | 婷婷五月综合缴情在线视频 | 荫蒂被男人添的好舒服爽免费视频 | 亚洲欧美精品伊人久久 | 精品无码成人片一区二区98 | 久久综合色之久久综合 | 久久无码中文字幕免费影院蜜桃 | 无码人妻精品一区二区三区不卡 | 东京一本一道一二三区 | 一本加勒比波多野结衣 | 亚洲国产欧美国产综合一区 | 色婷婷av一区二区三区之红樱桃 | 老熟妇仑乱视频一区二区 | 日韩 欧美 动漫 国产 制服 | 中文字幕无码视频专区 | 国产美女精品一区二区三区 | 国产亚洲视频中文字幕97精品 | 无码人妻丰满熟妇区毛片18 | 久久亚洲精品成人无码 | 欧美丰满少妇xxxx性 | 国产人妖乱国产精品人妖 | 免费观看激色视频网站 | 水蜜桃色314在线观看 | 色欲综合久久中文字幕网 | 少妇无套内谢久久久久 | 国产黑色丝袜在线播放 | 亚洲中文字幕va福利 | 蜜臀aⅴ国产精品久久久国产老师 | 国产精品二区一区二区aⅴ污介绍 | 亚洲国产精品无码一区二区三区 | 最近的中文字幕在线看视频 | 国产精品久久久久久无码 | 国产人妻精品午夜福利免费 | 日日噜噜噜噜夜夜爽亚洲精品 | 亚洲欧美精品伊人久久 | 亚洲精品一区二区三区四区五区 | 久久久久av无码免费网 | 国产莉萝无码av在线播放 | 中文字幕乱妇无码av在线 | 成人精品视频一区二区三区尤物 | 国产美女精品一区二区三区 | 国产亚洲精品久久久久久 | 日韩精品乱码av一区二区 | 内射巨臀欧美在线视频 | 97se亚洲精品一区 | 久久99精品国产麻豆蜜芽 | 亚洲精品成a人在线观看 | 国产真实乱对白精彩久久 | 亚洲日韩av一区二区三区四区 | 色欲久久久天天天综合网精品 | 久久精品人妻少妇一区二区三区 | 久久精品无码一区二区三区 | 国产片av国语在线观看 | 日日干夜夜干 | 国产精品无码一区二区桃花视频 | 日本护士毛茸茸高潮 | 青青草原综合久久大伊人精品 | 少妇被粗大的猛进出69影院 | 学生妹亚洲一区二区 | 日本精品高清一区二区 | 丁香啪啪综合成人亚洲 | 国产精品久久久久无码av色戒 | 久久精品国产99精品亚洲 | 精品无码国产一区二区三区av | 福利一区二区三区视频在线观看 | 久久99精品国产.久久久久 | 久久人人爽人人爽人人片av高清 | 国精品人妻无码一区二区三区蜜柚 | 伊人久久大香线蕉av一区二区 | 日韩精品无码免费一区二区三区 | 欧美日韩综合一区二区三区 | 亚洲国产欧美日韩精品一区二区三区 | 国产成人综合在线女婷五月99播放 | 一本久道高清无码视频 | 免费国产成人高清在线观看网站 | 国产精品欧美成人 | 国产av久久久久精东av | 亚洲精品中文字幕久久久久 | 国产色精品久久人妻 | 永久黄网站色视频免费直播 | 98国产精品综合一区二区三区 | 99麻豆久久久国产精品免费 | 色妞www精品免费视频 | 99久久久无码国产精品免费 | 亚洲中文无码av永久不收费 | 乱码午夜-极国产极内射 | 强伦人妻一区二区三区视频18 | 久久伊人色av天堂九九小黄鸭 | 国产口爆吞精在线视频 | 国产做国产爱免费视频 | 妺妺窝人体色www在线小说 | 无套内谢的新婚少妇国语播放 | 女人被爽到呻吟gif动态图视看 | 熟妇女人妻丰满少妇中文字幕 | 亚洲精品国偷拍自产在线麻豆 | 思思久久99热只有频精品66 | 亚洲一区二区观看播放 | 欧美成人家庭影院 | 成人无码精品一区二区三区 | 久久久久久久久888 | 男女猛烈xx00免费视频试看 | 丰满少妇熟乱xxxxx视频 | 极品嫩模高潮叫床 | av小次郎收藏 | 国产综合久久久久鬼色 | 久久午夜无码鲁丝片 | 亚洲精品午夜国产va久久成人 | 水蜜桃亚洲一二三四在线 | 国产肉丝袜在线观看 | 国产av一区二区精品久久凹凸 | av香港经典三级级 在线 | 欧美刺激性大交 | 国产精品人人爽人人做我的可爱 | 国产精品久久久久久久影院 | 熟妇人妻无码xxx视频 | 国语自产偷拍精品视频偷 | 麻花豆传媒剧国产免费mv在线 | 色综合久久久久综合一本到桃花网 | 国产农村乱对白刺激视频 | 久久99精品国产麻豆 | 国产成人综合色在线观看网站 | 亚洲中文字幕久久无码 | 中文字幕精品av一区二区五区 | 国产无av码在线观看 | 亚洲一区二区三区在线观看网站 | 午夜精品久久久久久久久 | 久久五月精品中文字幕 | 中文字幕日产无线码一区 | 成人无码精品1区2区3区免费看 | 人妻插b视频一区二区三区 | 日本精品人妻无码77777 天堂一区人妻无码 | 女人被男人爽到呻吟的视频 | 在线视频网站www色 | 亚洲国精产品一二二线 | 亚洲精品久久久久中文第一幕 | yw尤物av无码国产在线观看 | 娇妻被黑人粗大高潮白浆 | 国产特级毛片aaaaaaa高清 | 高潮毛片无遮挡高清免费 | 国产午夜福利100集发布 | 亚洲精品国产a久久久久久 | 国产精品99爱免费视频 | 人妻天天爽夜夜爽一区二区 | 蜜桃av抽搐高潮一区二区 | 色婷婷综合激情综在线播放 | 国产成人精品三级麻豆 | 国产亚洲精品久久久ai换 | 老熟女重囗味hdxx69 | 无码国内精品人妻少妇 | 久久久av男人的天堂 | 精品人妻av区 | 少妇人妻大乳在线视频 | 亚洲一区二区三区播放 | 欧美午夜特黄aaaaaa片 | 欧美国产亚洲日韩在线二区 | 沈阳熟女露脸对白视频 | 国产亚洲欧美在线专区 | 久久综合九色综合欧美狠狠 | 欧美性生交xxxxx久久久 | 鲁大师影院在线观看 | 国产亚洲人成在线播放 | 午夜男女很黄的视频 | 久久综合色之久久综合 | 中文字幕日产无线码一区 | 最近中文2019字幕第二页 | 精品国产成人一区二区三区 | 天堂亚洲2017在线观看 | 97夜夜澡人人双人人人喊 | 国产精品国产三级国产专播 | 少妇一晚三次一区二区三区 | 亚洲日韩一区二区三区 | 午夜精品久久久久久久久 | а天堂中文在线官网 | 草草网站影院白丝内射 | 野外少妇愉情中文字幕 | 波多野结衣av一区二区全免费观看 | 麻豆md0077饥渴少妇 | 国产口爆吞精在线视频 | 97精品人妻一区二区三区香蕉 | 久久久无码中文字幕久... | 人人妻人人藻人人爽欧美一区 | 国产成人无码一二三区视频 | 熟妇人妻无乱码中文字幕 | 亚洲人成影院在线无码按摩店 | 日韩少妇白浆无码系列 | 欧美 丝袜 自拍 制服 另类 | 又粗又大又硬又长又爽 | 性史性农村dvd毛片 | 日本一本二本三区免费 | 1000部夫妻午夜免费 | 精品无码一区二区三区的天堂 | 国产亚洲精品久久久久久久久动漫 | 成年美女黄网站色大免费全看 | 国产人妻人伦精品1国产丝袜 | 十八禁真人啪啪免费网站 | 国产精品欧美成人 | 在线天堂新版最新版在线8 | 久久久久人妻一区精品色欧美 | 日本欧美一区二区三区乱码 | 2020最新国产自产精品 | 动漫av网站免费观看 | 久久精品国产精品国产精品污 | 久久精品国产日本波多野结衣 | 免费人成网站视频在线观看 | 丰满人妻一区二区三区免费视频 | 亚洲中文字幕无码一久久区 | 4hu四虎永久在线观看 | 精品无码国产一区二区三区av | 久久www免费人成人片 | 国产麻豆精品一区二区三区v视界 | 四虎永久在线精品免费网址 | 色综合久久中文娱乐网 | 131美女爱做视频 | 欧美色就是色 | 性生交片免费无码看人 | 国产精品爱久久久久久久 | 色一情一乱一伦 | 国产真人无遮挡作爱免费视频 | 少妇性荡欲午夜性开放视频剧场 | 九九久久精品国产免费看小说 | 国产精品人人爽人人做我的可爱 | 国产国语老龄妇女a片 | 国产精品久久国产三级国 | 中文字幕日产无线码一区 | 人妻体内射精一区二区三四 | 国产精品无码一区二区桃花视频 | 国语自产偷拍精品视频偷 | 国产成人综合美国十次 | 丰满肥臀大屁股熟妇激情视频 | 亚洲精品综合一区二区三区在线 | 国产熟妇另类久久久久 | 日本xxxx色视频在线观看免费 | 2019nv天堂香蕉在线观看 | 色诱久久久久综合网ywww | 熟妇人妻激情偷爽文 | 蜜臀aⅴ国产精品久久久国产老师 | 国产精品嫩草久久久久 | 国产精品无码久久av | 亚洲欧洲日本综合aⅴ在线 | 黑人玩弄人妻中文在线 | 爆乳一区二区三区无码 | 国产精品-区区久久久狼 | 人妻与老人中文字幕 | 亚洲爆乳大丰满无码专区 | 久久综合九色综合欧美狠狠 | 国产精品高潮呻吟av久久4虎 | 欧美人与禽猛交狂配 | 久久国产精品精品国产色婷婷 | 久久伊人色av天堂九九小黄鸭 | 亚洲爆乳大丰满无码专区 | 国产在线精品一区二区高清不卡 | 西西人体www44rt大胆高清 | 人人超人人超碰超国产 | 色五月五月丁香亚洲综合网 | 樱花草在线社区www | 男人的天堂2018无码 | 国产成人久久精品流白浆 | 蜜臀av在线播放 久久综合激激的五月天 | 少妇无套内谢久久久久 | 亚洲精品成人av在线 | 亚洲综合无码一区二区三区 | 丝袜人妻一区二区三区 | 亚洲成av人影院在线观看 | 国产精品久久久久7777 | 国产精品欧美成人 | 亚洲人成无码网www | 精品国产麻豆免费人成网站 | 亚洲国产欧美日韩精品一区二区三区 | 久久国产精品_国产精品 | 天干天干啦夜天干天2017 | 国产精品人人妻人人爽 | 少女韩国电视剧在线观看完整 | 又大又硬又爽免费视频 | 性开放的女人aaa片 | 日韩人妻少妇一区二区三区 | 黑人巨大精品欧美黑寡妇 | 美女毛片一区二区三区四区 | 精品国偷自产在线 | 久久www免费人成人片 | 精品国产成人一区二区三区 | 国产舌乚八伦偷品w中 | 亚洲毛片av日韩av无码 | 中文字幕人成乱码熟女app | 四虎影视成人永久免费观看视频 | 国产精品多人p群无码 | 国产成人无码av片在线观看不卡 | 狂野欧美激情性xxxx | 精品欧洲av无码一区二区三区 | 麻豆国产人妻欲求不满谁演的 | 任你躁在线精品免费 | 欧美精品国产综合久久 | 丰满肥臀大屁股熟妇激情视频 | 欧美熟妇另类久久久久久不卡 | 成人片黄网站色大片免费观看 | 久久精品国产99精品亚洲 | 成人片黄网站色大片免费观看 | 亚洲va中文字幕无码久久不卡 | 美女张开腿让人桶 | 国产精品美女久久久 | 人妻无码αv中文字幕久久琪琪布 | 一本久道久久综合狠狠爱 | 国产精品无码一区二区桃花视频 | 久久国产精品偷任你爽任你 | 无码人妻精品一区二区三区下载 | 国产在热线精品视频 | 国产av一区二区精品久久凹凸 | 最新版天堂资源中文官网 | 久久精品成人欧美大片 | 麻豆md0077饥渴少妇 | 国产精品第一国产精品 | 亚洲精品午夜国产va久久成人 | 国产午夜亚洲精品不卡下载 | 又大又硬又爽免费视频 | 亚洲熟悉妇女xxx妇女av | 亚洲国产欧美日韩精品一区二区三区 | 精品国产福利一区二区 | 日日摸夜夜摸狠狠摸婷婷 | 波多野结衣一区二区三区av免费 | а天堂中文在线官网 | 99久久人妻精品免费一区 | 午夜精品久久久内射近拍高清 | 亚洲春色在线视频 | 亚洲第一无码av无码专区 | 国産精品久久久久久久 | 日本一本二本三区免费 | 亚洲人亚洲人成电影网站色 | 欧美黑人性暴力猛交喷水 | 三上悠亚人妻中文字幕在线 | 综合人妻久久一区二区精品 | 国产乱人伦偷精品视频 | 久久国内精品自在自线 | 日本又色又爽又黄的a片18禁 | 国产午夜亚洲精品不卡 | 性做久久久久久久久 | 97无码免费人妻超级碰碰夜夜 | 久久精品无码一区二区三区 | 精品久久久久久人妻无码中文字幕 | 欧美午夜特黄aaaaaa片 | 国产肉丝袜在线观看 | 日韩人妻无码中文字幕视频 | 精品一区二区三区无码免费视频 | 国产色精品久久人妻 | 色偷偷av老熟女 久久精品人妻少妇一区二区三区 | 亚洲熟女一区二区三区 | 精品无码国产一区二区三区av | 乱人伦中文视频在线观看 | 久久精品国产日本波多野结衣 | 色情久久久av熟女人妻网站 | 日韩精品无码免费一区二区三区 | 午夜成人1000部免费视频 | 精品一二三区久久aaa片 | 精品人妻人人做人人爽夜夜爽 | 天堂无码人妻精品一区二区三区 | 夜夜高潮次次欢爽av女 | 久久久无码中文字幕久... | 国产97在线 | 亚洲 | 免费中文字幕日韩欧美 | 国产成人精品视频ⅴa片软件竹菊 | 欧美黑人性暴力猛交喷水 | 亚洲另类伦春色综合小说 | 人妻少妇精品无码专区动漫 | 激情五月综合色婷婷一区二区 | 亚洲欧美综合区丁香五月小说 | 国产精品美女久久久 | 俄罗斯老熟妇色xxxx | 蜜桃av抽搐高潮一区二区 | 娇妻被黑人粗大高潮白浆 | 疯狂三人交性欧美 | 日本www一道久久久免费榴莲 | 久久久久人妻一区精品色欧美 | 无码人妻av免费一区二区三区 | 性做久久久久久久免费看 | 日产精品99久久久久久 | 三上悠亚人妻中文字幕在线 | 国产精品久久久久9999小说 | 无码午夜成人1000部免费视频 | 欧美阿v高清资源不卡在线播放 | 3d动漫精品啪啪一区二区中 | 伊人久久大香线蕉午夜 | 精品无码成人片一区二区98 | 久久久久人妻一区精品色欧美 | 欧美人与善在线com | 中文精品久久久久人妻不卡 | 欧美性生交活xxxxxdddd | 国产精品久久久久9999小说 | 在线播放免费人成毛片乱码 | 国产色xx群视频射精 | 十八禁视频网站在线观看 | 久久久中文久久久无码 | 白嫩日本少妇做爰 | 色偷偷av老熟女 久久精品人妻少妇一区二区三区 | 东京无码熟妇人妻av在线网址 | 在线播放无码字幕亚洲 | 成人一在线视频日韩国产 | 国产超碰人人爽人人做人人添 | 国产sm调教视频在线观看 | 一本色道婷婷久久欧美 | 亚洲一区av无码专区在线观看 | 蜜桃臀无码内射一区二区三区 | 亚洲精品久久久久久久久久久 | 成人欧美一区二区三区 | 少妇厨房愉情理9仑片视频 | 麻豆md0077饥渴少妇 | 成人欧美一区二区三区黑人免费 | 极品尤物被啪到呻吟喷水 | 欧美人与禽猛交狂配 | 国产超碰人人爽人人做人人添 | 5858s亚洲色大成网站www | 天天做天天爱天天爽综合网 | 丰满少妇人妻久久久久久 | 四虎4hu永久免费 | 亚洲а∨天堂久久精品2021 | 国产明星裸体无码xxxx视频 | 熟妇激情内射com | 日韩精品无码一区二区中文字幕 | 人妻人人添人妻人人爱 | 午夜福利试看120秒体验区 | 99久久久无码国产精品免费 | 97精品国产97久久久久久免费 | 亚洲成av人影院在线观看 | 人人妻人人藻人人爽欧美一区 | 中文字幕日产无线码一区 | 国产一区二区三区影院 | 国产九九九九九九九a片 | 欧美猛少妇色xxxxx | 成人欧美一区二区三区黑人 | 99久久久国产精品无码免费 | 人妻天天爽夜夜爽一区二区 | 日本欧美一区二区三区乱码 | 国产亚洲tv在线观看 | 大地资源中文第3页 | 正在播放东北夫妻内射 | 国产av一区二区三区最新精品 | 亚洲性无码av中文字幕 | 少妇性荡欲午夜性开放视频剧场 | 久久久精品成人免费观看 | 老熟女乱子伦 | 国产成人无码a区在线观看视频app | 精品国产精品久久一区免费式 | 18黄暴禁片在线观看 | 熟妇人妻激情偷爽文 | 成 人影片 免费观看 | 欧美人与禽猛交狂配 | 亚洲va欧美va天堂v国产综合 | 玩弄人妻少妇500系列视频 | 久久久久99精品成人片 | 欧美激情综合亚洲一二区 | 国产综合久久久久鬼色 | 成人亚洲精品久久久久软件 | 久久国产精品_国产精品 | 欧美日韩一区二区三区自拍 | 久久久久成人片免费观看蜜芽 | 激情人妻另类人妻伦 | 小sao货水好多真紧h无码视频 | 东京热无码av男人的天堂 | 亚洲精品成人福利网站 | 亚洲国产精品一区二区第一页 | 日本熟妇乱子伦xxxx | 麻豆精产国品 | 精品亚洲韩国一区二区三区 | 国内精品人妻无码久久久影院 | 扒开双腿吃奶呻吟做受视频 | 国产又粗又硬又大爽黄老大爷视 | 亚洲自偷自拍另类第1页 | 亚洲另类伦春色综合小说 | a在线观看免费网站大全 | 黑人巨大精品欧美黑寡妇 | 久久亚洲中文字幕无码 | 亚洲精品鲁一鲁一区二区三区 | 99国产精品白浆在线观看免费 | 国精品人妻无码一区二区三区蜜柚 | 日本又色又爽又黄的a片18禁 | 精品人妻中文字幕有码在线 | 婷婷色婷婷开心五月四房播播 | 少妇无码一区二区二三区 | 国产午夜亚洲精品不卡下载 | 亚洲欧洲无卡二区视頻 | 亚洲男人av香蕉爽爽爽爽 | 久青草影院在线观看国产 | 老司机亚洲精品影院无码 | 内射巨臀欧美在线视频 | 午夜不卡av免费 一本久久a久久精品vr综合 | 精品国产aⅴ无码一区二区 | 99re在线播放 | 久久精品国产大片免费观看 | 蜜臀av无码人妻精品 | 人妻少妇精品久久 | 亚洲成色在线综合网站 | 欧洲精品码一区二区三区免费看 | 亚洲一区二区三区在线观看网站 | 夜先锋av资源网站 | 一本久久a久久精品亚洲 | 欧美猛少妇色xxxxx | 精品无码国产一区二区三区av | 两性色午夜视频免费播放 | 欧美zoozzooz性欧美 | 狠狠综合久久久久综合网 | 18黄暴禁片在线观看 | 精品厕所偷拍各类美女tp嘘嘘 | 高清不卡一区二区三区 | 成人无码精品一区二区三区 | 2020久久香蕉国产线看观看 | 300部国产真实乱 | 日本一区二区更新不卡 | 国内精品人妻无码久久久影院蜜桃 | 国产精品-区区久久久狼 | 无码吃奶揉捏奶头高潮视频 | 国产激情精品一区二区三区 | 在线а√天堂中文官网 | 青青青手机频在线观看 | 无码人中文字幕 | 午夜精品久久久久久久 | 黑森林福利视频导航 | 无码人妻出轨黑人中文字幕 | 精品国产一区二区三区av 性色 | 精品人妻中文字幕有码在线 | 国产 精品 自在自线 | 国内精品久久毛片一区二区 | 99精品国产综合久久久久五月天 | 丰满妇女强制高潮18xxxx | 亚洲中文字幕成人无码 | 久久久久亚洲精品男人的天堂 | 国产精品国产自线拍免费软件 | 一个人免费观看的www视频 | 激情综合激情五月俺也去 | 亚洲中文字幕久久无码 | 亚洲大尺度无码无码专区 | 欧美肥老太牲交大战 | 人妻人人添人妻人人爱 | 国产亚洲美女精品久久久2020 | 精品久久久无码中文字幕 | 天天摸天天透天天添 | 露脸叫床粗话东北少妇 | 性欧美牲交xxxxx视频 | 四虎4hu永久免费 | 人妻夜夜爽天天爽三区 | 欧美日韩综合一区二区三区 | 国产精品资源一区二区 | 四虎影视成人永久免费观看视频 | 日欧一片内射va在线影院 | 少妇太爽了在线观看 | 久久人妻内射无码一区三区 | 亚洲色无码一区二区三区 | 国产精品久久久久久亚洲毛片 | 乌克兰少妇性做爰 | 久久亚洲中文字幕无码 | 久久视频在线观看精品 | 俺去俺来也www色官网 | 狠狠色噜噜狠狠狠狠7777米奇 | v一区无码内射国产 | 欧美丰满熟妇xxxx性ppx人交 | 在线精品亚洲一区二区 | 丝袜足控一区二区三区 | 天天拍夜夜添久久精品 | 国产特级毛片aaaaaa高潮流水 | 无码国产色欲xxxxx视频 | 夜精品a片一区二区三区无码白浆 | 欧美日本日韩 | 中文精品久久久久人妻不卡 | 色诱久久久久综合网ywww | 欧美人与物videos另类 | 98国产精品综合一区二区三区 | 蜜臀av在线播放 久久综合激激的五月天 | 欧美熟妇另类久久久久久不卡 | 久久综合九色综合欧美狠狠 | 成人免费视频一区二区 | 色狠狠av一区二区三区 | 人人妻人人澡人人爽欧美一区 | 精品日本一区二区三区在线观看 | 日韩av无码一区二区三区 | 国内少妇偷人精品视频免费 | 欧美国产亚洲日韩在线二区 | 国产色视频一区二区三区 | 国内综合精品午夜久久资源 | 乱码午夜-极国产极内射 | 亚洲日韩一区二区三区 | 国产精品第一国产精品 | 一本精品99久久精品77 | 中文字幕日产无线码一区 | 久久久亚洲欧洲日产国码αv | 99国产欧美久久久精品 | 99久久精品午夜一区二区 | 色综合视频一区二区三区 | 国产福利视频一区二区 | 在线观看欧美一区二区三区 | 久久视频在线观看精品 | 一本久道高清无码视频 | 国产在线一区二区三区四区五区 | 亚洲小说图区综合在线 | 中文字幕av无码一区二区三区电影 | 狂野欧美性猛xxxx乱大交 | 荫蒂添的好舒服视频囗交 | 亚洲日韩中文字幕在线播放 | 99视频精品全部免费免费观看 | 国产精品va在线播放 | 亚洲а∨天堂久久精品2021 | 欧美老妇与禽交 | 亚洲成a人一区二区三区 | 精品国产乱码久久久久乱码 | 亚洲综合精品香蕉久久网 | 国产午夜亚洲精品不卡 | 国内精品人妻无码久久久影院 | 久久熟妇人妻午夜寂寞影院 | 国产手机在线αⅴ片无码观看 | 亚洲精品www久久久 | 无码中文字幕色专区 | 亚洲综合色区中文字幕 | ass日本丰满熟妇pics | 丰满人妻被黑人猛烈进入 | 亚洲精品成人av在线 | 国产一区二区不卡老阿姨 | 日本一区二区更新不卡 | 精品国产乱码久久久久乱码 | 国产欧美熟妇另类久久久 | 国产亚洲日韩欧美另类第八页 | 丰满妇女强制高潮18xxxx | 欧美熟妇另类久久久久久不卡 | 人人爽人人澡人人人妻 | 精品日本一区二区三区在线观看 | 亚洲人成网站在线播放942 | 人妻夜夜爽天天爽三区 | 亚洲 日韩 欧美 成人 在线观看 | 久久久久人妻一区精品色欧美 | 国产97在线 | 亚洲 | 欧美国产日韩久久mv | 亚洲精品综合五月久久小说 | 欧美老妇与禽交 | 免费人成在线视频无码 | 波多野结衣 黑人 | 欧美国产日产一区二区 | 欧美日本免费一区二区三区 | 国产精品无码久久av | 黑人粗大猛烈进出高潮视频 | 男人和女人高潮免费网站 | 成人精品一区二区三区中文字幕 | 亚洲小说春色综合另类 | 亚洲中文字幕久久无码 | 日本又色又爽又黄的a片18禁 | 国产人妻人伦精品 | 美女扒开屁股让男人桶 | 少妇人妻偷人精品无码视频 | 亚洲一区二区三区香蕉 | 日韩精品一区二区av在线 | 久久精品国产一区二区三区肥胖 | 国产av一区二区精品久久凹凸 | 青青青爽视频在线观看 | 婷婷五月综合缴情在线视频 | yw尤物av无码国产在线观看 | 久久亚洲国产成人精品性色 | 久久久亚洲欧洲日产国码αv | 成年女人永久免费看片 | 中文字幕亚洲情99在线 | 午夜理论片yy44880影院 | 人妻少妇精品视频专区 | 国产午夜视频在线观看 | 亚洲一区二区三区国产精华液 | 熟妇激情内射com | 亚洲欧美精品aaaaaa片 | 99久久亚洲精品无码毛片 | 67194成是人免费无码 | 少妇性俱乐部纵欲狂欢电影 | 夜夜高潮次次欢爽av女 | 亚洲一区二区三区香蕉 | 久久久久久久女国产乱让韩 | 精品无码一区二区三区爱欲 | 未满小14洗澡无码视频网站 | 久久精品成人欧美大片 | 99久久久无码国产aaa精品 | 亚洲成av人在线观看网址 | 精品人人妻人人澡人人爽人人 | 在教室伦流澡到高潮hnp视频 | 欧美一区二区三区视频在线观看 | 久久久久久亚洲精品a片成人 | 免费人成在线观看网站 | 精品国产aⅴ无码一区二区 | 久久国产精品_国产精品 | 欧美丰满老熟妇xxxxx性 | 亚洲一区二区三区国产精华液 | 午夜福利一区二区三区在线观看 | 人妻体内射精一区二区三四 | аⅴ资源天堂资源库在线 | 免费乱码人妻系列无码专区 | 性生交片免费无码看人 | 国产亚洲人成在线播放 | 中文字幕 人妻熟女 | 在线视频网站www色 | 精品无码成人片一区二区98 | 一本大道久久东京热无码av | 久久久久久亚洲精品a片成人 | 波多野42部无码喷潮在线 | 精品乱子伦一区二区三区 | 国产精品人人爽人人做我的可爱 | 永久免费观看美女裸体的网站 | 无遮挡国产高潮视频免费观看 | 夜夜躁日日躁狠狠久久av | 亚洲天堂2017无码中文 | 国产综合在线观看 | 99久久久无码国产精品免费 | 久久久无码中文字幕久... | 久久人妻内射无码一区三区 | 国产乱人伦av在线无码 | 亚洲自偷自拍另类第1页 | 亚洲一区二区三区无码久久 | 男女作爱免费网站 | 日韩av无码一区二区三区 | 奇米综合四色77777久久 东京无码熟妇人妻av在线网址 | 最近免费中文字幕中文高清百度 | 丰满少妇高潮惨叫视频 | 亚洲色成人中文字幕网站 | 国产真实乱对白精彩久久 | 国产熟妇高潮叫床视频播放 | 少妇高潮喷潮久久久影院 | 97夜夜澡人人爽人人喊中国片 | 免费国产成人高清在线观看网站 | 少妇的肉体aa片免费 | 麻豆人妻少妇精品无码专区 | 国产suv精品一区二区五 | 成人女人看片免费视频放人 | 无码精品国产va在线观看dvd | 麻豆成人精品国产免费 | 日韩无套无码精品 | 无码人妻精品一区二区三区下载 | 亚洲精品成人福利网站 | 无码av免费一区二区三区试看 | 亚洲午夜福利在线观看 | 久久久精品人妻久久影视 | 丁香啪啪综合成人亚洲 | 国产乱人伦app精品久久 国产在线无码精品电影网 国产国产精品人在线视 | 夜精品a片一区二区三区无码白浆 | 曰本女人与公拘交酡免费视频 | 免费视频欧美无人区码 | 色五月丁香五月综合五月 | 一本色道婷婷久久欧美 | 永久免费精品精品永久-夜色 | 老子影院午夜伦不卡 | 国产成人无码区免费内射一片色欲 | 久久久久99精品国产片 | 乌克兰少妇xxxx做受 | 天天躁日日躁狠狠躁免费麻豆 | 国产农村乱对白刺激视频 | 对白脏话肉麻粗话av | 夫妻免费无码v看片 | 中文字幕 亚洲精品 第1页 | 人人澡人人透人人爽 | 国内综合精品午夜久久资源 | 天天摸天天透天天添 | 亚洲精品久久久久久久久久久 | 无码人妻丰满熟妇区毛片18 | 免费网站看v片在线18禁无码 | 欧美国产日韩亚洲中文 | 成人亚洲精品久久久久 | 日日干夜夜干 | 国产精品第一国产精品 | 人妻少妇精品无码专区二区 | 成人女人看片免费视频放人 | 久9re热视频这里只有精品 | 国产精品毛片一区二区 | 国产精品高潮呻吟av久久 | 高中生自慰www网站 | 午夜精品一区二区三区的区别 | 丰满岳乱妇在线观看中字无码 | 国精产品一品二品国精品69xx | 性啪啪chinese东北女人 | 在线观看免费人成视频 | 亚洲区欧美区综合区自拍区 | 免费国产成人高清在线观看网站 | 国内精品久久毛片一区二区 | 对白脏话肉麻粗话av | 国产黄在线观看免费观看不卡 | 午夜免费福利小电影 | 亚洲欧美中文字幕5发布 | 国产精品免费大片 | 亚洲 欧美 激情 小说 另类 | 成人精品视频一区二区三区尤物 | 99国产欧美久久久精品 | 97久久精品无码一区二区 | 国产精品多人p群无码 | 国产精品无码成人午夜电影 | 午夜成人1000部免费视频 | 亚洲中文字幕无码一久久区 | 西西人体www44rt大胆高清 | 正在播放老肥熟妇露脸 | 国产后入清纯学生妹 | 欧美自拍另类欧美综合图片区 | 成人无码视频免费播放 | 人人妻人人澡人人爽欧美一区九九 | 领导边摸边吃奶边做爽在线观看 | 中文字幕+乱码+中文字幕一区 | 麻豆果冻传媒2021精品传媒一区下载 | 久久视频在线观看精品 | 4hu四虎永久在线观看 | 蜜桃av蜜臀av色欲av麻 999久久久国产精品消防器材 | 成人无码精品1区2区3区免费看 | 日本va欧美va欧美va精品 | 婷婷五月综合缴情在线视频 | 亚洲精品中文字幕乱码 | 中文字幕无码人妻少妇免费 | 久久五月精品中文字幕 | 玩弄人妻少妇500系列视频 | 中文字幕人妻丝袜二区 | 美女扒开屁股让男人桶 | 熟妇人妻中文av无码 | 波多野结衣 黑人 | 97久久超碰中文字幕 | 99麻豆久久久国产精品免费 | 粉嫩少妇内射浓精videos | 国产极品视觉盛宴 | 激情五月综合色婷婷一区二区 | 国产精品嫩草久久久久 | 国产高清av在线播放 | 丰满岳乱妇在线观看中字无码 | 乱人伦人妻中文字幕无码 | 动漫av一区二区在线观看 | 欧美激情综合亚洲一二区 | 18黄暴禁片在线观看 | 性欧美videos高清精品 | 男女猛烈xx00免费视频试看 | 一本色道久久综合亚洲精品不卡 | 久久亚洲中文字幕无码 | 久久久久人妻一区精品色欧美 | 波多野42部无码喷潮在线 | 中文字幕人妻无码一区二区三区 | 精品无码国产一区二区三区av | 亚洲欧洲中文日韩av乱码 | 亚洲欧美日韩国产精品一区二区 | 特级做a爰片毛片免费69 | 久久久国产精品无码免费专区 | 欧美一区二区三区 | 中文字幕无线码 | 国产成人精品必看 | 影音先锋中文字幕无码 | 色狠狠av一区二区三区 | 无套内射视频囯产 | 亚洲日本va中文字幕 | 天天摸天天碰天天添 | 国产片av国语在线观看 | 无码人妻少妇伦在线电影 | 欧美 丝袜 自拍 制服 另类 | 欧美日本精品一区二区三区 | 宝宝好涨水快流出来免费视频 | 人妻无码久久精品人妻 | 亚洲日韩av一区二区三区四区 | 国产综合在线观看 | 国产疯狂伦交大片 | 九月婷婷人人澡人人添人人爽 | 国产精品香蕉在线观看 | 久久无码中文字幕免费影院蜜桃 | 一个人看的www免费视频在线观看 | 人人澡人摸人人添 | 高中生自慰www网站 | 亚洲小说春色综合另类 | 爽爽影院免费观看 | 亚洲成a人片在线观看无码3d | 久久亚洲日韩精品一区二区三区 | 亚洲国产精品久久久久久 | 国产午夜福利100集发布 | 亚洲七七久久桃花影院 | 亚洲色大成网站www国产 | 无遮挡啪啪摇乳动态图 | 亚洲国产精品成人久久蜜臀 | 日本丰满护士爆乳xxxx | 久久人人97超碰a片精品 | 帮老师解开蕾丝奶罩吸乳网站 | 天天燥日日燥 | 国产艳妇av在线观看果冻传媒 | 免费国产黄网站在线观看 | 国产精品无码一区二区三区不卡 | 色综合久久久久综合一本到桃花网 | 午夜熟女插插xx免费视频 | 18禁黄网站男男禁片免费观看 | 久久久精品国产sm最大网站 | 欧美午夜特黄aaaaaa片 | 国产精品无码一区二区桃花视频 | 欧美国产日韩久久mv | 日韩欧美群交p片內射中文 | 久久久久成人精品免费播放动漫 | 国产精品人人妻人人爽 | 亚洲精品国产a久久久久久 | 国产亚洲精品久久久久久国模美 | 日本爽爽爽爽爽爽在线观看免 | 暴力强奷在线播放无码 | 宝宝好涨水快流出来免费视频 | 熟女俱乐部五十路六十路av | 亚洲国产精品久久久久久 | 极品嫩模高潮叫床 | 台湾无码一区二区 | 亚洲 a v无 码免 费 成 人 a v | 性生交大片免费看l | 久久久久se色偷偷亚洲精品av | 国产精品办公室沙发 | 男女下面进入的视频免费午夜 | 狠狠cao日日穞夜夜穞av | 婷婷综合久久中文字幕蜜桃三电影 | 蜜桃臀无码内射一区二区三区 | 亚洲日韩av片在线观看 | 特级做a爰片毛片免费69 | 76少妇精品导航 | 亚洲国产精品无码一区二区三区 | 正在播放东北夫妻内射 | 鲁鲁鲁爽爽爽在线视频观看 | 久久久久亚洲精品中文字幕 | 岛国片人妻三上悠亚 | 国产口爆吞精在线视频 | 国产综合在线观看 | 中文亚洲成a人片在线观看 | 正在播放东北夫妻内射 | 久久熟妇人妻午夜寂寞影院 | 国内综合精品午夜久久资源 | 国产综合色产在线精品 | 77777熟女视频在线观看 а天堂中文在线官网 | 一本加勒比波多野结衣 | 亚洲欧洲中文日韩av乱码 | 日韩 欧美 动漫 国产 制服 | 国产精品18久久久久久麻辣 | 亚洲国产精品久久久久久 | 高潮毛片无遮挡高清免费 | 国产亚洲欧美在线专区 | 亚洲一区二区三区偷拍女厕 | 九月婷婷人人澡人人添人人爽 | 亚洲成av人在线观看网址 | 日本一区二区更新不卡 | 亚洲成色在线综合网站 | 日本乱人伦片中文三区 | 欧美一区二区三区视频在线观看 | 欧美性猛交内射兽交老熟妇 | 久久99精品国产麻豆 | 男女超爽视频免费播放 | 国产疯狂伦交大片 | 国产卡一卡二卡三 | 丰满人妻精品国产99aⅴ | 欧美刺激性大交 | 亚洲 欧美 激情 小说 另类 | 亚洲中文字幕久久无码 | 色欲久久久天天天综合网精品 | 一区二区传媒有限公司 | 亚洲国产一区二区三区在线观看 | 曰本女人与公拘交酡免费视频 | 久久成人a毛片免费观看网站 | 国产精品高潮呻吟av久久4虎 | 美女极度色诱视频国产 | 亚洲成熟女人毛毛耸耸多 | 老熟妇乱子伦牲交视频 | 精品国精品国产自在久国产87 | 无码av免费一区二区三区试看 | 午夜熟女插插xx免费视频 | 无码午夜成人1000部免费视频 | 婷婷丁香六月激情综合啪 | 欧美成人高清在线播放 | 亚洲大尺度无码无码专区 | 国产精品无码成人午夜电影 | 国内精品九九久久久精品 | 国产亚洲美女精品久久久2020 | 日韩精品乱码av一区二区 | 色综合久久88色综合天天 | 欧美zoozzooz性欧美 | 国产亚洲欧美日韩亚洲中文色 | 国产精品亚洲综合色区韩国 | 高潮毛片无遮挡高清免费视频 | 国产精品va在线观看无码 | 国产农村妇女高潮大叫 | 欧美熟妇另类久久久久久多毛 | 国内精品一区二区三区不卡 | 亚洲成a人片在线观看无码 | 蜜桃无码一区二区三区 | 大色综合色综合网站 | 中文字幕人妻丝袜二区 | 中国大陆精品视频xxxx | 成人免费视频在线观看 | 大屁股大乳丰满人妻 | 久久99精品久久久久婷婷 | 天天躁夜夜躁狠狠是什么心态 | 东京一本一道一二三区 | 在线天堂新版最新版在线8 | 欧美zoozzooz性欧美 | 性欧美大战久久久久久久 | 99精品视频在线观看免费 | 国产麻豆精品精东影业av网站 | 亚洲国产一区二区三区在线观看 | 一本大道久久东京热无码av | 久久精品国产精品国产精品污 | 97久久精品无码一区二区 | 亚洲大尺度无码无码专区 | 欧美精品国产综合久久 | 欧美人与禽猛交狂配 | 人妻互换免费中文字幕 | 欧美日本精品一区二区三区 | 国产在热线精品视频 | 老司机亚洲精品影院 | 无码人妻丰满熟妇区毛片18 | 欧美大屁股xxxxhd黑色 |