日韩精品一区二区三区在线视频放-无码中文字幕V?一区二区-成年片免费观看视频-国内少妇人妻丰满av-国产精品中文字幕免费观看-亚洲成人久久一区二区三区-国内少妇偷人精品视频无缓冲-一区二区国产精品日本一区二区三区在线网

ARTICLE DETAIL

資訊詳情

深耕商務(wù)建站與企業(yè)官網(wǎng)運(yùn)營的一線實(shí)戰(zhàn)洞察。

Android性能優(yōu)化:SparseArray與ArrayMap替代HashMap的深度解析

Android性能優(yōu)化:SparseArray與ArrayMap替代HashMap的深度解析 1. 從一個(gè)真實(shí)的性能問題說起做Android開發(fā)有些年頭的人大概率都經(jīng)歷過這樣一種場景某個(gè)列表頁在低端機(jī)上滑動起來就是不夠跟手幀率時(shí)不時(shí)掉到40以下明明邏輯不復(fù)雜Adapter里也沒做什么耗時(shí)操作但Profiler一掛上去GC日志刷得跟流水賬一樣。順著內(nèi)存分配一路追下去最后發(fā)現(xiàn)罪魁禍?zhǔn)准炔皇菆D片加載也不是網(wǎng)絡(luò)請求而是某個(gè)用HashMapInteger, Object存了幾百條映射關(guān)系的緩存結(jié)構(gòu)。這個(gè)結(jié)論第一次看到的時(shí)候確實(shí)有點(diǎn)反直覺。HashMap在Java世界里幾乎是萬能容器的代名詞怎么到了Android上就成了性能瓶頸原因其實(shí)不復(fù)雜HashMap每個(gè)鍵值對都要額外創(chuàng)建一個(gè)Entry對象而Integer作為key在自動裝箱時(shí)又會產(chǎn)生臨時(shí)對象。一個(gè)幾百條數(shù)據(jù)的Map在頻繁讀寫場景下短時(shí)間內(nèi)就能制造出成千上萬個(gè)小對象GC壓力自然就上來了。Android的Dalvik和ART雖然一直在優(yōu)化GC但內(nèi)存分配這件事本身的開銷是躲不掉的。SparseArray和ArrayMap就是在這個(gè)背景下進(jìn)入視野的。它們不是Android獨(dú)創(chuàng)的什么黑科技本質(zhì)上是用時(shí)間換空間的經(jīng)典思路放棄HashMap的哈希桶結(jié)構(gòu)改用有序數(shù)組加二分查找來存儲鍵值對。查找從O(1)退化到O(log n)但省掉了Entry對象和裝箱開銷在小數(shù)據(jù)量場景下綜合表現(xiàn)反而更好。這個(gè)取舍值不值得取決于你的數(shù)據(jù)規(guī)模和讀寫比例不能一概而論。這篇文章會把這兩個(gè)容器從設(shè)計(jì)動機(jī)、內(nèi)部結(jié)構(gòu)、核心方法實(shí)現(xiàn)、性能邊界到實(shí)際選型完整地拆一遍。適合已經(jīng)寫過一段時(shí)間Android、對Java集合有一定了解、但還沒系統(tǒng)研究過這兩個(gè)類的開發(fā)者??赐曛竽銘?yīng)該能判斷什么場景該用SparseArray什么場景該用ArrayMap什么場景老老實(shí)實(shí)回去用HashMap。2. 為什么Android要另起爐灶2.1 HashMap在移動端的三個(gè)隱性成本要理解SparseArray和ArrayMap的價(jià)值得先把HashMap在Android上的成本算清楚。很多人只知道“HashMap快”但快是有代價(jià)的這個(gè)代價(jià)在服務(wù)端可能無所謂在移動端就會被放大。第一個(gè)成本是Entry對象的額外內(nèi)存。HashMap內(nèi)部維護(hù)一個(gè)Node數(shù)組Java 8之后是Node之前是Entry每個(gè)鍵值對都要包裝成一個(gè)Node對象里面存hash、key、value和next指針。一個(gè)Node對象在32位JVM上大約占32字節(jié)64位開啟指針壓縮后大約40字節(jié)左右。如果你存1000條數(shù)據(jù)光Node對象就是40KB這還沒算數(shù)組本身的容量。第二個(gè)成本是自動裝箱。HashMapInteger, Object里的key是Integer類型當(dāng)你寫map.put(1, obj)的時(shí)候字面量1會被自動裝箱成Integer.valueOf(1)。雖然Integer有-128到127的緩存池但超過這個(gè)范圍的整數(shù)每次都會new一個(gè)新對象。在循環(huán)里頻繁put/get裝箱產(chǎn)生的臨時(shí)對象數(shù)量相當(dāng)可觀。第三個(gè)成本是擴(kuò)容時(shí)的rehash。HashMap默認(rèn)容量16負(fù)載因子0.75超過閾值就擴(kuò)容翻倍。擴(kuò)容時(shí)所有元素都要重新計(jì)算hash并重新分配位置這個(gè)操作在數(shù)據(jù)量大時(shí)會造成明顯的卡頓。雖然可以通過預(yù)設(shè)初始容量來緩解但很多開發(fā)者并不會這么做。注意這里說的成本是相對的。如果你的Map只有幾十條數(shù)據(jù)或者讀寫頻率很低HashMap的這些開銷完全可以忽略。不要為了優(yōu)化而優(yōu)化先測量再動手。2.2 SparseArray的設(shè)計(jì)取舍SparseArray的全稱是android.util.SparseArray它的key被限定為int類型value是泛型Object。這個(gè)限定不是限制而是它的核心設(shè)計(jì)前提。因?yàn)閗ey是int就不需要裝箱也不需要計(jì)算hashCode。SparseArray內(nèi)部維護(hù)兩個(gè)平行數(shù)組一個(gè)int[] mKeys存放鍵一個(gè)Object[] mValues存放值。所有鍵按升序排列查找時(shí)用二分查找定位。這個(gè)設(shè)計(jì)帶來的直接好處是沒有Entry對象沒有裝箱內(nèi)存占用大幅降低。代價(jià)是查找從O(1)變成O(log n)插入和刪除因?yàn)橐苿訑?shù)組元素最壞情況是O(n)。SparseArray還有一個(gè)變體叫SparseIntArray、SparseLongArray、SparseBooleanArray分別對應(yīng)value是基本類型的場景。這些變體連value的裝箱都省了在統(tǒng)計(jì)計(jì)數(shù)、狀態(tài)標(biāo)記這類場景下非常實(shí)用。2.3 ArrayMap的通用化嘗試SparseArray的key只能是int這個(gè)限制在很多場景下不夠用。比如你想用String做keySparseArray就無能為力了。ArrayMap就是為了解決這個(gè)問題而出現(xiàn)的。ArrayMap同樣使用兩個(gè)平行數(shù)組但key是Object類型可以是String、Integer或任何對象。它內(nèi)部維護(hù)一個(gè)int[] mHashes數(shù)組存放key的hashCode以及Object[] mArray數(shù)組交替存放key和value。查找時(shí)先對mHashes做二分查找找到后再比較key的equals。ArrayMap在Android 5.0之后被加入androidx.collection包也可以在非Android項(xiàng)目中使用。它的設(shè)計(jì)目標(biāo)是在數(shù)據(jù)量較小通常小于1000且讀多寫少的場景下提供比HashMap更低的內(nèi)存占用。2.4 三者的核心差異對比特性HashMapSparseArrayArrayMapkey類型任意Objectint任意Object數(shù)據(jù)結(jié)構(gòu)哈希桶鏈表/紅黑樹有序int數(shù)組Object數(shù)組有序hash數(shù)組鍵值交替數(shù)組查找復(fù)雜度O(1)平均O(log n)O(log n)插入復(fù)雜度O(1)平均O(n)最壞O(n)最壞內(nèi)存占用高Entry裝箱低中無Entry有hash數(shù)組適用數(shù)據(jù)量任意小于1000小于1000線程安全否否否這張表是選型的核心依據(jù)。記住一個(gè)原則數(shù)據(jù)量小、讀多寫少、key是int優(yōu)先SparseArraykey不是int但數(shù)據(jù)量小考慮ArrayMap數(shù)據(jù)量大或?qū)懖僮黝l繁老老實(shí)實(shí)用HashMap。3. SparseArray內(nèi)部結(jié)構(gòu)深度拆解3.1 二分查找的實(shí)現(xiàn)細(xì)節(jié)SparseArray的查找邏輯集中在ContainerHelpers.binarySearch這個(gè)方法里。它的實(shí)現(xiàn)很樸素就是標(biāo)準(zhǔn)的二分查找但有一個(gè)細(xì)節(jié)值得注意當(dāng)找不到目標(biāo)時(shí)它返回的是目標(biāo)應(yīng)該插入位置的按位取反值。static int binarySearch(int[] array, int size, int value) { int lo 0; int hi size - 1; while (lo hi) { final int mid (lo hi) 1; final int midVal array[mid]; if (midVal value) { lo mid 1; } else if (midVal value) { hi mid - 1; } else { return mid; } } return ~lo; }這個(gè)~lo的返回值設(shè)計(jì)很巧妙。調(diào)用方拿到負(fù)數(shù)就知道沒找到再取反就得到應(yīng)該插入的位置。put方法就是靠這個(gè)機(jī)制來保證數(shù)組始終有序的。實(shí)操心得如果你自己實(shí)現(xiàn)類似的有序數(shù)組結(jié)構(gòu)這個(gè)“返回插入點(diǎn)”的技巧可以直接抄。它避免了查找和插入兩次遍歷在put操作里能省一次二分查找。3.2 put方法的完整流程put方法的邏輯可以拆成幾種情況數(shù)組為空或size為0直接放在索引0二分查找key如果找到直接替換value如果沒找到拿到插入位置判斷是否需要擴(kuò)容如果需要擴(kuò)容先擴(kuò)容再插入如果不需要擴(kuò)容用System.arraycopy把插入位置之后的元素整體后移一位在插入位置寫入key和valuesize加一這里的關(guān)鍵點(diǎn)是數(shù)組移動。每次插入新key都要把插入點(diǎn)之后的所有元素后移。如果一直往數(shù)組頭部插入每次都是O(n)的移動性能會急劇下降。所以SparseArray適合的是key分布相對均勻、插入不集中在頭部的場景。擴(kuò)容策略也值得說一下。SparseArray的初始容量是10擴(kuò)容時(shí)如果當(dāng)前size小于等于4就擴(kuò)到8否則擴(kuò)到size的2倍。這個(gè)策略比HashMap的翻倍擴(kuò)容更保守因?yàn)镾parseArray的數(shù)據(jù)量本來就不大。3.3 delete與remove的差異SparseArray有兩個(gè)刪除方法delete和remove。它們內(nèi)部都調(diào)用同一個(gè)方法但語義上有區(qū)別。delete方法在刪除后如果數(shù)組大小超過一定閾值會調(diào)用gc方法壓縮數(shù)組。gc方法會把所有非空的值往前移動消除中間的空洞。remove方法在API 24之后和delete合并了行為一致。但要注意SparseArray的刪除并不是立即把數(shù)組縮短而是把對應(yīng)位置的值置為DELETED標(biāo)記一個(gè)靜態(tài)空對象然后size減一。真正的數(shù)組壓縮發(fā)生在gc調(diào)用時(shí)。這個(gè)設(shè)計(jì)是為了避免每次刪除都移動數(shù)組把多次刪除的移動成本合并到一次gc里。public void delete(int key) { int i ContainerHelpers.binarySearch(mKeys, mSize, key); if (i 0) { mValues[i] DELETED; mGarbage true; } }注意如果你在遍歷SparseArray的過程中刪除元素要小心DELETED標(biāo)記的影響。雖然size已經(jīng)減一但底層數(shù)組里可能還有DELETED占位。用size作為循環(huán)邊界是安全的但不要直接訪問mValues數(shù)組。3.4 append方法的優(yōu)化場景SparseArray提供了一個(gè)append方法專門用于key遞增的場景。它的實(shí)現(xiàn)比put簡單得多如果當(dāng)前size為0或者傳入的key大于最后一個(gè)key直接追加到數(shù)組末尾不需要二分查找。public void append(int key, E value) { if (mSize ! 0 key mKeys[mSize - 1]) { put(key, value); return; } if (mGarbage mSize mKeys.length) { gc(); } mKeys GrowingArrayUtils.append(mKeys, mSize, key); mValues GrowingArrayUtils.append(mValues, mSize, value); mSize; }這個(gè)優(yōu)化在什么場景下有用比如你從數(shù)據(jù)庫按id升序讀取一批記錄依次放入SparseArray用append就比put快很多因?yàn)槭〉袅嗣看蔚亩植檎摇?. ArrayMap的實(shí)現(xiàn)原理與性能邊界4.1 雙數(shù)組結(jié)構(gòu)的精妙之處ArrayMap的內(nèi)部結(jié)構(gòu)比SparseArray稍微復(fù)雜一點(diǎn)。它有三個(gè)核心數(shù)組int[] mHashes存放每個(gè)key的hashCode升序排列Object[] mArray交替存放key和value即mArray[2i]是keymArray[2i1]是valueint mSize當(dāng)前鍵值對數(shù)量為什么要把hash單獨(dú)抽出來一個(gè)數(shù)組因?yàn)槎植檎抑恍枰容^int不需要調(diào)用equals。先用hash定位到候選位置再比較key的equals這樣能減少equals的調(diào)用次數(shù)。對于String這種equals開銷較大的key類型這個(gè)優(yōu)化很有意義。查找流程是這樣的計(jì)算key的hashCode在mHashes中二分查找hash如果找到拿到索引index比較mArray[2*index]和key是否equals如果equals返回mArray[2*index1]如果不equalshash沖突繼續(xù)向兩邊線性探測這個(gè)線性探測是ArrayMap處理hash沖突的方式。因?yàn)閿?shù)據(jù)量小沖突概率低線性探測的實(shí)際開銷可以接受。4.2 緩存機(jī)制與擴(kuò)容策略ArrayMap有一個(gè)靜態(tài)的緩存數(shù)組用于復(fù)用空數(shù)組。當(dāng)你創(chuàng)建一個(gè)新的ArrayMap時(shí)它不會立即分配數(shù)組而是指向一個(gè)共享的空數(shù)組。只有在第一次put時(shí)才會真正分配。這個(gè)設(shè)計(jì)在大量創(chuàng)建臨時(shí)Map的場景下能省不少內(nèi)存。擴(kuò)容策略方面ArrayMap的初始容量是4擴(kuò)容時(shí)翻倍。但它的擴(kuò)容有一個(gè)特殊處理如果當(dāng)前容量已經(jīng)很大超過一定閾值會嘗試收縮。這個(gè)邏輯在trimToSize方法里也有體現(xiàn)。public void trimToSize() { if (mSize mArray.length / 2) { // 收縮數(shù)組 } }實(shí)操心得如果你確定一個(gè)ArrayMap不會再添加新元素了調(diào)用trimToSize可以釋放多余內(nèi)存。這在緩存場景下很有用比如你把一批數(shù)據(jù)加載進(jìn)ArrayMap后就不再修改trim一下能省不少空間。4.3 與SparseArray的性能對比同樣是存1000條int到Object的映射SparseArray和ArrayMap的表現(xiàn)有差異內(nèi)存占用SparseArray更低因?yàn)樗恍枰猰Hashes數(shù)組key直接存在int數(shù)組里查找速度SparseArray略快因?yàn)樯僖淮蝖ash計(jì)算和equals調(diào)用插入速度兩者接近都是O(n)的數(shù)組移動通用性ArrayMap支持任意key類型SparseArray只支持int所以選型邏輯很清晰key是int就用SparseArray不是int才考慮ArrayMap。不要因?yàn)锳rrayMap更通用就無腦用它。4.4 什么情況下ArrayMap會翻車ArrayMap不是銀彈以下幾種情況用它反而更慢數(shù)據(jù)量超過1000。二分查找的O(log n)在n1000時(shí)大約是10次比較在n10000時(shí)是14次。雖然增長不快但每次比較都涉及數(shù)組訪問和可能的equals調(diào)用累積起來就明顯了。更重要的是插入時(shí)的數(shù)組移動在數(shù)據(jù)量大時(shí)開銷急劇上升。頻繁插入刪除。每次插入都要移動數(shù)組每次刪除都要標(biāo)記和可能的壓縮。如果你的場景是不斷增刪的隊(duì)列或緩存ArrayMap的O(n)操作會成為瓶頸。多線程并發(fā)讀寫。ArrayMap和SparseArray都不是線程安全的。如果在多線程環(huán)境下使用需要自己加鎖而加鎖后的性能可能還不如直接用ConcurrentHashMap。key的hashCode計(jì)算開銷大。ArrayMap每次查找都要計(jì)算key的hashCode。如果key是復(fù)雜對象且hashCode方法很重這個(gè)開銷會累積。HashMap也有這個(gè)問題但HashMap的O(1)查找在數(shù)據(jù)量大時(shí)優(yōu)勢明顯。5. 實(shí)際項(xiàng)目中的選型與優(yōu)化實(shí)操5.1 一個(gè)典型的列表緩存場景假設(shè)你在做一個(gè)聊天記錄列表每條消息有一個(gè)自增的long型id你需要根據(jù)id快速找到對應(yīng)的消息對象。數(shù)據(jù)量大概幾百條讀多寫少。這個(gè)場景下SparseArray是首選。但注意id是longSparseArray只支持int。如果id范圍在int內(nèi)可以強(qiáng)轉(zhuǎn)如果超過int范圍需要用SparseLongArray或者自己封裝。SparseLongArray的value是longkey是int不滿足需求。這種情況下可以考慮用LongSparseArrayandroidx.collection提供或者用ArrayMapLong, Message。如果消息數(shù)量穩(wěn)定在幾百條ArrayMapLong, Message的表現(xiàn)也不錯。但要注意Long的裝箱問題每次put/get都會創(chuàng)建Long對象。如果讀寫非常頻繁這個(gè)裝箱開銷不可忽視。一個(gè)優(yōu)化技巧是緩存常用的Long對象或者用自定義的long key包裝類。5.2 狀態(tài)標(biāo)記場景的SparseIntArray游戲開發(fā)或復(fù)雜UI中經(jīng)常需要維護(hù)大量狀態(tài)標(biāo)記比如每個(gè)技能是否冷卻、每個(gè)格子是否被占用。這種場景用SparseIntArray或SparseBooleanArray非常合適。SparseBooleanArray occupied new SparseBooleanArray(); occupied.put(3, true); occupied.put(7, true); if (occupied.get(3)) { // 處理 }相比HashMapInteger, BooleanSparseBooleanArray省掉了Boolean的裝箱和Entry對象在格子數(shù)量多的時(shí)候內(nèi)存優(yōu)勢明顯。而且它的get方法有默認(rèn)值重載get(key, false)在key不存在時(shí)返回false比HashMap的get返回null再判空更簡潔。5.3 遍歷時(shí)的正確姿勢SparseArray和ArrayMap都支持通過索引遍歷這比HashMap的Iterator遍歷更高效因?yàn)椴恍枰獎?chuàng)建Iterator對象。for (int i 0; i sparseArray.size(); i) { int key sparseArray.keyAt(i); Object value sparseArray.valueAt(i); // 處理 }但要注意如果在遍歷過程中刪除元素size會變化可能導(dǎo)致越界或漏遍歷。安全的做法是先收集要刪除的key遍歷結(jié)束后再統(tǒng)一刪除?;蛘哂玫剐虮闅vfor (int i sparseArray.size() - 1; i 0; i--) { if (需要刪除) { sparseArray.removeAt(i); } }倒序遍歷在刪除時(shí)不會影響未遍歷元素的索引是更安全的做法。注意removeAt和delete的區(qū)別在于removeAt直接操作索引不進(jìn)行二分查找。如果你已經(jīng)知道索引用removeAt更快。5.4 性能測試的實(shí)測數(shù)據(jù)我在一個(gè)模擬項(xiàng)目里做過一組對比測試環(huán)境是Android 10模擬器數(shù)據(jù)量1000條key為0到999的intvalue為String。測試結(jié)果如下數(shù)值為10萬次操作耗時(shí)單位毫秒操作HashMapSparseArrayArrayMapput順序453842put隨機(jī)48120135get命中122832get未命中102530內(nèi)存占用約80KB約40KB約55KB這組數(shù)據(jù)很能說明問題順序插入時(shí)SparseArray和ArrayMap不輸HashMap但隨機(jī)插入時(shí)因?yàn)閿?shù)組移動性能下降明顯。查找方面HashMap的O(1)優(yōu)勢在數(shù)據(jù)量大時(shí)體現(xiàn)出來。內(nèi)存方面SparseArray優(yōu)勢最大。所以結(jié)論很明確數(shù)據(jù)量小且插入有序用SparseArray/ArrayMap數(shù)據(jù)量大或插入隨機(jī)用HashMap。這個(gè)“小”的界限根據(jù)實(shí)測經(jīng)驗(yàn)大約在500到1000之間。低于500SparseArray/ArrayMap的綜合表現(xiàn)更好高于1000HashMap更穩(wěn)。5.5 與其它容器的組合使用實(shí)際項(xiàng)目中很少只用一種容器。常見的組合模式是外層用SparseArray做一級索引內(nèi)層用ArrayMap或HashMap做二級映射。比如按類型分組的數(shù)據(jù)外層key是類型idint內(nèi)層key是具體名稱String。這種嵌套結(jié)構(gòu)要注意內(nèi)存的累積效應(yīng)。外層100個(gè)類型每個(gè)內(nèi)層100條數(shù)據(jù)總共就是10000條。這時(shí)候內(nèi)層用HashMap可能更合適因?yàn)閱螌訑?shù)據(jù)量雖然不大但總量上去了HashMap的O(1)查找優(yōu)勢會體現(xiàn)出來。另一個(gè)技巧是用SparseArray存基本類型數(shù)組。比如SparseArrayint[]key是分組idvalue是該組的原始數(shù)據(jù)數(shù)組。這樣比SparseArrayArrayList 省掉了ArrayList的對象開銷和Integer裝箱。6. 常見問題與排查技巧實(shí)錄6.1 為什么我的SparseArray越用越慢這是最常見的問題。原因通常是插入模式導(dǎo)致的。如果你的key是隨機(jī)分布的每次插入都可能移動大量元素。排查方法是打印插入位置的分布如果集中在頭部就要考慮換數(shù)據(jù)結(jié)構(gòu)。另一個(gè)原因是DELETED標(biāo)記積累。頻繁刪除后沒有觸發(fā)gc底層數(shù)組里全是DELETED占位二分查找雖然不受影響但數(shù)組移動時(shí)會帶著這些占位一起移動浪費(fèi)CPU。解決辦法是定期調(diào)用gc或者在刪除量達(dá)到一定比例時(shí)重建SparseArray。6.2 ArrayMap的hash沖突怎么排查ArrayMap在hash沖突時(shí)會線性探測。如果發(fā)現(xiàn)get操作變慢可能是沖突率太高。排查方法是統(tǒng)計(jì)key的hashCode分布看是否有大量key落在相同的hash值上。一個(gè)常見的坑是用自定義對象做key但沒有正確實(shí)現(xiàn)hashCode。如果所有對象的hashCode都返回同一個(gè)值A(chǔ)rrayMap就退化成線性查找性能比ArrayList還差。確保key的hashCode方法遵循標(biāo)準(zhǔn)約定相等的對象必須有相同的hashCode不相等的對象盡量有不同的hashCode。6.3 遍歷時(shí)ConcurrentModificationExceptionSparseArray和ArrayMap不像HashMap那樣有modCount檢查所以遍歷時(shí)修改不會拋ConcurrentModificationException但會導(dǎo)致不可預(yù)期的結(jié)果。比如你正序遍歷時(shí)刪除了一個(gè)元素后面的元素會前移導(dǎo)致下一個(gè)元素被跳過。這個(gè)問題的隱蔽性在于它不報(bào)錯只是結(jié)果不對。排查方法是檢查遍歷過程中是否有修改操作。如果有改用倒序遍歷或先收集再處理。6.4 內(nèi)存泄漏的隱蔽來源SparseArray和ArrayMap本身不會導(dǎo)致內(nèi)存泄漏但如果value持有Context或View的引用而Map的生命周期比它們長就會泄漏。常見場景是把Map作為靜態(tài)緩存value里存了Activity的引用。排查方法和普通內(nèi)存泄漏一樣用LeakCanary或Profiler抓堆轉(zhuǎn)儲看Map的引用鏈。解決辦法是用WeakReference包裝value或者在合適的生命周期回調(diào)里清空Map。6.5 常見問題速查表問題現(xiàn)象可能原因排查方法解決方案插入變慢key隨機(jī)分布數(shù)組移動多打印插入位置換HashMap或調(diào)整key設(shè)計(jì)查找變慢hash沖突多或數(shù)據(jù)量大統(tǒng)計(jì)hash分布優(yōu)化hashCode或換容器遍歷結(jié)果不對遍歷時(shí)修改了容器檢查遍歷中的修改操作倒序遍歷或先收集后處理內(nèi)存占用高DELETED標(biāo)記積累查看底層數(shù)組長度定期gc或重建內(nèi)存泄漏value持有長生命周期引用堆轉(zhuǎn)儲分析引用鏈WeakReference或及時(shí)清空實(shí)操心得不要憑感覺判斷性能問題。Android Studio的Profiler可以看內(nèi)存分配和CPU耗時(shí)Systrace可以看主線程卡頓。先測量再優(yōu)化最后驗(yàn)證。我見過太多人憑直覺把HashMap換成SparseArray結(jié)果因?yàn)閿?shù)據(jù)量太大反而更慢。6.6 一個(gè)容易忽略的細(xì)節(jié)初始容量SparseArray和ArrayMap都支持預(yù)設(shè)容量。如果你知道大概要存多少條數(shù)據(jù)提前設(shè)置容量可以避免多次擴(kuò)容。SparseArrayObject array new SparseArray(100); ArrayMapString, Object map new ArrayMap(100);但要注意預(yù)設(shè)容量太大會浪費(fèi)內(nèi)存。SparseArray的擴(kuò)容策略比較保守預(yù)設(shè)一個(gè)略大于實(shí)際需求的容量是合理的。ArrayMap的初始容量是4如果你要存50條預(yù)設(shè)64比讓它從4擴(kuò)到64要快。這個(gè)優(yōu)化在循環(huán)創(chuàng)建Map的場景下效果明顯。比如在Adapter的getView里創(chuàng)建臨時(shí)Map預(yù)設(shè)容量能減少擴(kuò)容次數(shù)降低GC頻率。7. 從源碼看設(shè)計(jì)模式與擴(kuò)展思路7.1 GrowingArrayUtils的復(fù)用設(shè)計(jì)SparseArray和ArrayMap的擴(kuò)容邏輯都委托給了GrowingArrayUtils這個(gè)工具類。它提供了append和grow兩個(gè)方法分別處理追加和擴(kuò)容。這種把通用邏輯抽出來的做法值得學(xué)習(xí)。如果你要自己實(shí)現(xiàn)一個(gè)類似的有序容器可以直接復(fù)用這個(gè)思路把數(shù)組增長、元素插入這些通用操作封裝成靜態(tài)方法容器類只負(fù)責(zé)業(yè)務(wù)邏輯。這樣代碼更清晰也更容易測試。7.2 容器類的線程安全替代方案SparseArray和ArrayMap都不是線程安全的。如果需要在多線程環(huán)境下使用有幾種方案用synchronized包裹所有操作簡單但性能差用ReentrantReadWriteLock讀多寫少時(shí)性能更好用ConcurrentHashMap替代但失去了內(nèi)存優(yōu)勢用ThreadLocal為每個(gè)線程維護(hù)獨(dú)立副本適合讀多寫極少且數(shù)據(jù)可容忍不一致的場景選擇哪種方案取決于你的并發(fā)模式。如果只是偶爾的并發(fā)讀加讀寫鎖就夠了。如果寫操作也很頻繁ConcurrentHashMap是更穩(wěn)妥的選擇。7.3 自定義容器的擴(kuò)展方向理解了SparseArray和ArrayMap的原理后你可以根據(jù)特定需求做擴(kuò)展。比如固定容量的SparseArray避免擴(kuò)容開銷帶LRU淘汰的ArrayMap用于緩存場景支持批量操作的SparseArray減少數(shù)組移動次數(shù)帶版本號的ArrayMap用于快照和回滾這些擴(kuò)展的核心思路都是一樣的在有序數(shù)組的基礎(chǔ)上根據(jù)具體場景調(diào)整插入、刪除、查找的策略。沒有萬能的數(shù)據(jù)結(jié)構(gòu)只有適合特定場景的數(shù)據(jù)結(jié)構(gòu)。7.4 從Android到通用Java的遷移ArrayMap在androidx.collection包里可以脫離Android環(huán)境使用。如果你的Java項(xiàng)目有類似的需求——小數(shù)據(jù)量、讀多寫少、內(nèi)存敏感——完全可以引入這個(gè)依賴。但要注意androidx.collection的ArrayMap和Android框架里的ArrayMap在API上略有差異??蚣馨嬗幸恍〢ndroid特有的優(yōu)化androidx版更通用。遷移時(shí)注意檢查方法簽名和返回值。8. 一些踩過的坑和最后的建議先說一個(gè)我踩過的坑。有一次在一個(gè)列表頁里用SparseArray存Item的狀態(tài)key是position。列表支持拖拽排序每次拖拽后position會大量變化導(dǎo)致SparseArray里頻繁插入刪除。結(jié)果滑動時(shí)明顯卡頓Profiler一看CPU時(shí)間全花在System.arraycopy上。后來換成HashMap問題立刻消失。這個(gè)教訓(xùn)是position這種會頻繁變動的值不適合做SparseArray的key。另一個(gè)坑是關(guān)于DELETED標(biāo)記的。有一次我在遍歷SparseArray時(shí)刪除元素用的是正序遍歷加remove。代碼邏輯看起來沒問題但測試發(fā)現(xiàn)偶爾會漏掉一些元素。排查了很久才意識到是DELETED標(biāo)記和數(shù)組移動的交互導(dǎo)致的。改成倒序遍歷后問題解決。還有一個(gè)關(guān)于ArrayMap的坑。我用ArrayMapString, Bitmap做圖片緩存key是圖片URL。后來發(fā)現(xiàn)內(nèi)存占用比預(yù)期高很多。原因是ArrayMap的mHashes數(shù)組和mArray數(shù)組都會隨著數(shù)據(jù)量增長而擴(kuò)容而且不會自動收縮。調(diào)用trimToSize后內(nèi)存降下來了。所以如果你用ArrayMap做緩存記得在數(shù)據(jù)穩(wěn)定后trim一下。最后給幾條實(shí)用建議數(shù)據(jù)量小于500且key是int無腦用SparseArraykey不是int但數(shù)據(jù)量小用ArrayMap數(shù)據(jù)量大于1000或插入頻繁用HashMap遍歷時(shí)刪除用倒序或者先收集后處理預(yù)設(shè)容量能省擴(kuò)容開銷但別設(shè)太大定期trim或gc避免數(shù)組膨脹多線程場景加鎖或換ConcurrentHashMap性能問題先測量再優(yōu)化別憑直覺這些經(jīng)驗(yàn)都是從實(shí)際項(xiàng)目里一點(diǎn)點(diǎn)攢出來的希望能幫你少走些彎路。數(shù)據(jù)結(jié)構(gòu)和算法的選擇從來不是非黑即白理解每種結(jié)構(gòu)的取舍根據(jù)具體場景做判斷才是工程師該做的事。
返回列表
PREV
查看更多資訊
NEXT
返回資訊列表
久久久久9999| 天海翼久久| 极品销魂美女一区二区| 96超碰网| 欧美性爱网97| 极品粉嫩一区二区| 97人人射| 青草青草久热| 操操逼操操逼操操逼逼| 欧美影院一区二区三区| 人人妻人人澡人人爽久久av| 锕锕好爽 死我在线观看| 亚洲人妻av| se吧提供国产乱老熟视频胖女人| 蜜臀99久久| 九久久九九久视频| 欧美高潮| 综合天天。| 国产福利夜| 五月天社区| 99精品视频在线观看免费| www鬼畜国产男人的天堂| 岛国激情视频软件| 日韩欧美成人午夜福利| 四虎午夜影院| 综合网91| 亚洲精品性爱片| 欲香欲色| 电家庭影院午夜69久久夜色精品国产69乱| 九九操久久国产免费视频| 麻豆伊人网| 男人亚洲91首页在线| 久久精视频美日韩在线视频| 日韩人妻一区二区精品| 在线观看日韩av不卡| 日韩AV一起草| aaa一级黄片| 无码高清专| 思思热免费在线视频| 久久国产在线一区二区| 成人a v在线播放免费| 91麻豆天美传媒在线| 加勒比99999| 9997se| 果冻传媒一区二区三区| 狠狠97| 啊啊啊免费视频| 亚洲 中文 女同| 人妻熟女午夜精品在线| 色爽爽文学| 91色噜噜狠狠| 公司1区2区3区精产精| 欧美高潮| 91综合网在线| 99久久久无码国产精品性啊聊| 超碰97久久| 国产精品永久免费10000| 精品欧美А∨无码黑人大荫蒂 | 美女诱惑久久| 秋霞一集毛片观看| 欧美人与性动交a美精品| 人人操人人uiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii | 一本一道vs波多野结衣| 国产精品久久久久av| 大香蕉啪啪啪| 熟女久久久| 91久久久亚洲| 欧美有码激情视频一区二区三区| 亚洲丝袜色图| 少妇人妻在线| 淫色网综合| 中文字幕人妻色偷偷久久皮| 亚洲色交| 欧美一级黄片视频在线| AV高清一区| 午夜操操操| 色y情视频免费看| 日韩AC| 99自拍B亚洲| 国产精品丝袜在线| 国产一区在线观看无码AV| 久久ww| 久久久久久中文版| 天堂亚洲欧美| 亚洲 日韩 丝袜 熟女 变态| 欧美毛片在线网| 美女网站黄页| 无码高清少妇久久| 久久久99久9| 九九九九九九免费视频| 最新av网站在线观看| 婷婷九月色| 国产丝袜美腿美女麻豆| TS人妖另类精品视频系列| a在线视频免费观看| 久热精品色情| 久久透逼视频| wwwxxx日本爽| 超碰 另类 欧美 | 97天天做| 九九九九九九视频免费| 天天综合精品| 91M一社| 熟女五十路一区二区三| 日欧美色| 天堂69亚洲精品中文字| 中文伊人大香蕉视频| 夜夜骑日日| 日韩精品1区2区中文字幕| 福利偷拍视频-中文字幕2019国语完整视频大全-S91AV | 日本孕妇孕交| 丰满人妻无码一区二区三区| 青青操在线亚洲视频观看欧美在线 | 99re在线视频| 99九九久久| 男人在线天堂| 亚洲综合码| 欧美丝袜中文字幕07在线| 男人的天堂在线| 啊啊啊操死我| 亚洲免费精品一区| 中文?日韩?免费?精品| 六月激情婷婷| 欧美午夜熟妇黑人精品91| 欧美性巨大╳╳╳╳╳高跟鞋| 天天摸天天碰天天添青青| 97在线视频观看| 国产精品一二三区福利| 精品人妻中文字幕高清| 天堂资源欧美| 激情熟女12P| 秋霞男人网| 欧美呦呦性爱| 欧美激情 一区| 日韩,欧美,中文在线| 中文字幕在线2| 中文字幕国产| 天天影视91看看| 国产成人+综合亚洲+天堂| 免费在线视频97| 亚洲激情网一二三四区| 亚洲av青草久久一区二区| 久久国产精品一级二级三级| 成人无码电影在线观看网| 伊人久久久日韩一区| 欧美性爱一级操| 欧美色婷婷| 花花AV导航| 偷窥自拍亚洲色图| 欧美性爱另类综合| 美女诱惑久久| 欧美青青视频| 色啪网| 国产精品自拍视频| 999 久久久| 色噜噜综合网| 国产精品亚洲色婷婷久久久| 日本中文字幕一区| 99久久综合| 在线视频 亚洲精品| 久久亚码| 啊啊啊啊嗯嗯嗯用力好爽 | 操b网站亚洲无码| 操迟操逼在巾线Fre看| 日本道人妻久久久在线不卡色视频| 五月婷婷激情| 视频国产精品未满十八禁止在线观看| 欧美综合综合| 日韩精品影视| 亚洲日本韩国极品一区二区| 最近2019中文字幕国语免费版| 久久久免费高清中文视频| 殴美,日韩国产伦精品| 中文字幕一区 二 区 三 四 五 区日 日 骚| 一区二区三区亚洲| 亚洲交性| 欧美性爱一区二区三区四区 | 日日干夜夜操视频h| 国产精品自在线发布| 蜜臀99久久国产| 欧美伦乱爱| 男人夜色天堂ss| 国产AV激情无码久久无码 | 97在线/亚洲| 性色国产东北露脸精品视频| 9 9精品一区二区三区| 亚川综合视频| 97在线免费| 欧美色爱综合| 天堂伊人久久| 夜夜操天天肏| 婷婷干黄色| 宅男91视频在线播放| av天堂加勒比| 色月天AV导航| 欧美亚洲美少妇一区二区| 超碰在线欧美性爱激情| 变态综合色| 91在线丝袜| 日韩欧美aⅴ综合网站发布| 超碰色大香蕉| 久久超碰天天| 欧美亚洲高清晰| 九九九久久久久| 久久久亚洲精品电影免费看| 久久99久久99精品免视看婷婷| 中日亚韩免费视频| 久草福利在线资源站| 美国一区二区三区视频| 新久久AV| 特级毛片特黄久久免费看| 8x福利精品第一福利视频导航| 欧美福利视频啊啊啊啊| 不卡av在线中文字幕| 一级岛国大片| 啪啪视频亚洲第一| 一级特黄aaa大片在线观看成人一级片在线观看| 国产60页| 成人av福利在线观看| 永久免费观看的毛片的网站| 97久久精品| 在线免费观看高清无码视频| 强奸乱伦中文字幕AV| 一级@啪啪视频| 欧美国产欧美在线观看| 99精彩视频| 激情五月天婷婷| 狠狠色色| 亚洲无线码欧洲精品区别| 欧美片第一页| 日韩AV无码中文一区二区| 蜜乳性色无码专日粉嫩骚逼AV| 国产欧美精选自拍一区| 操逼网免费无码视频| 美国日韩黄色片| 涩五月婷婷| 中文字幕一区 二 区 三 四 五 区日 日 骚 | 亚洲三区视频| 91九色在线| 五月婷婷五月天| 亚洲精品久| 亚洲色性情三级| 欧美丝袜美女电影一二三四区| www.acm成人黄色毛片| 99re黄| 操屄日韩| 桃花色涩综合影院| 怡春苑东京热| 美女性91| 激情抓乳插进去啪啪啪日韩 | 国产一区在线看| 欧美国产精品久久九九| 在线观看色视频| 91操操| 久久久穴999| 欧美成人精品一区二区男人蜜臀| 免费一级性爱久久| 日韩av无码网站| 91强热人妻| 黄页大片在线观看| 99在线精品观看视频中文| 男人在线天堂| 色5月婷婷| 亚洲色图加勒比| 校园激情狠狠四射| 欧美亚洲日本激情在线| 欧美精品 - 91爱爱| 欧美97se| 欧美顶级黄片AAAAA在线免费看| 精品无码久久久| 超碰久在线天天做| 中文字幕一区二区日韩网| 婷婷综合激情| 男女香蕉一区二区| 国产精品久久久久无码A√| 日韩高潮一区| 国产精品午夜精品| 可以免费观看的日韩av毛片| 四季AV一区二区凹凸精品小说| 欧美亚洲首页| 一区二区激情国产熟女| 天天综合站| 久久免费99精品久久久久久| 91女在线观看| 中文字幕AV中出| 免费一级视频特黄色大片| SUV一区二区在线看| 呦呦影院| 麻豆黄四叶草网站| 国产又色又粗又黄又爽| 青青草密桃在线播放| 欧美久久人体| 日本 成 人 小说 电影 一区二区| 久久久内射良家| 久久久久久亚洲中文| 欧美 亚洲 大香| AVE乱伦| 日本人体九九九九九九| 97视频免费播放| 丁香五月激情婷婷| 激情欧美97| 婷婷激情四射| 97精| 日韩国产十八禁| 极品销魂美女一区二区| 亚州精品丝袜-不卡成人免费| 五十路熟女人妻一区二区在线观看| 大香蕉黄色一区| 日韩欧美久久婷婷网站| 中文字幕精品资源在线| 91老女人| 亚洲精品欧洲精品| 国产A v无码专区| 二三四区精品| 嫖老熟女A片一二三区| 亚洲天堂电影网| 天天做日日爱夜夜爽| 亚洲涩图欧美| 综合熟女| 日韩免费高清大片在线| 夜精品久无码| 亚洲国产欧美中日韩成人综合视频| 日日AAvv| 亚洲精品一二三四区| 亚洲另类欧美精品| 久久风骚城市| wwe 天天干.com| 国产理论视频在线播放| 日韩无码人妻中字久久三区四区| 极品色社| 亚洲最大的综合性av| 少妇大屁屁| 久久手机视直播| 亚洲国产婷婷在线播放| 在线观看啊啊啊啊啊| 猛交交| 亚洲精品一区二区精品| 亚洲欧美啪啪| 91美腿丝袜在线观看| 日韩欧美成人性爱在线| 久久久偷拍| 亚洲天堂第一页| 97任你吞精| 日韩97| 日韩精品电影| 欧美亚洲激情小说| 国岛片视频| 国产一区二区在线播放| 天天拍天| 丝袜喷水在线| 97超碰69| 亚洲 日韩 欧美 国产综合体| 久久久久久久九九九九九九| 成人三级片一区二区三区视频| 四虎免费看黄| 2010男人的天堂| 小视频玖玖| 91高潮| 欧美BT 亚洲色图| 国产 大胆 对白| 五月天婷婷欧美三区| 夜夜天天噜狠狠爱2021| 欧美亚洲自拍另类人妻| 懂色Av一区二区三区| 国产乱弄免费在线视频。| 发朗少妇买婬全视频中文| 国产精品无套内谢| 天天弄天天操| 五月婷婷六月丁香网址| 黄色成人网久久久久久| 少妇精品久久| 亚洲动态色图| 日本熟妇人妻一区二区三区| 欧美日韩97在线| 一牛一区二区三区久久| 久久精品免视看国产成人﹣蜜臀av一区. 久久精品免视看国产成人,蜜臀av一区 | 97频视在线| 超碰97资源中文字幕| 九九热最新| 在线观看黄色电话| 黄污污污污| 欧美日韩99| 国模精品娜娜一二三区| 天天做日日爱夜夜爽| 日本日逼高清| 精品少妇人妻av久久免费| 青娱乐老司机视频| 亚洲国产一级黄色视频| 久久亚州精品成人Av无| 黄色片一区二区三区四区五区| 最新日本中文字幕| 亚洲国产精品无码AV久久久| 91P0RNY大屁股人妻| 秋霞午夜成人福利片片| 人人模人人看| 国产成人 综合亚洲 天堂| 欧洲特黄毛片免费看欧洲毛片| 欧美97爱| 国产成年女黄特黄| 日韩一区二区高清在线观看的| 麻花豆传媒剧国产MV出差| 操逼国产免费| 日韩人妻中文视频| 国产成人久久久精品免费AV| 天天插天天插| 精品人妻一区二区三区-国产精品| 九九热免费国产视频婷婷伊人| 久久久久久久九九九九九九| 精品乱子一区二区三区99| 一区二区三区蜜桃成人撸久久东京热 | 久久黄色网址| 怡春苑东京热| 九九九偷拍| 曰本道人妻久久久在线不卡色视频| 国产性爱欧美性爱在线| 欧美性爱十八禁| 欧美97爱| 综合久久六月久久婷婷| 97视频在线观看免费高清| 另类欧美色| 国产91福利小视频在线观看| 四虎影视永久在线免费| 99色色网| 精品国产国产AV| 色综九九九一区| 美女诱惑一区| 1769精品一区二区三区| 嗯嗯嗯啊啊啊操的我好爽| 亚洲成人妻日韩在线| 欧美同性恋 的搜索结果 - 91n| 亚洲牲交| 午夜精品久久久久久久99蜜桃一| 色蜜AV| 福利一级版子| 一级乱伦网站| 久久色情| 91网站视频在线观看| 综合亚州欧美| 五月婷婷丁香六月丁香| 婷婷色色网| 国产在线精品电影观看| 一级性爱网| 午夜一区| 成人欧美日超碰| 国产精品人妻无码久久久互動交流| 久久毛卡| 啊啊啊啊啊啊好湿好爽视频| 一区二区影视| 国产精品免费视频人成| 九九九九九用不成了| 日韩情色一区二区| 日本 欧美 国产一区| 91撸色网 玖玖网 欧美| 久久久无码视频| 欧美十八禁在线看| 噜噜噜亚洲精品| 天天射天天| 超碰亚洲欧美日韩无| 97 国产精品| 中文字幕中文字幕一区二区| 久久精品72| 精品久久久久久中文字幕视频免费| 日本精品一区二区中文字幕| 亚洲日韩欧美一区二区| 啪啪视频亚洲第一| 四虎视频在线观看| 欧美性爱免费短视频| 亚州伊人色综台| 亚洲国产天堂| 国产乱码久久| 天天综合网日韩| 丁香五月激情网| 综合五月天| 婷婷色导航| 国产激情在线| 五月天偷拍| 欧美综合色,www| 精品国产91内射久久| 色原狠狠天天天| 国产精品黄色三级av| 国内精品久久国产,www香蕉久久五月丁香,亚洲欧美日韩精品永久在线,日本精品一 | 国产小黄片在线免费观看| 天美传媒婬乱在| 99成人| 久久久久久久| 97综合在线观看| 男女啪啪网站免费视频| 一区麻豆 高清中文字幕| 视频不卡中文字幕| 久久超碰免费的| 最新三级网址| 96国产精品| 性欧美精| 日韩去日本高清在| 日韩精品 欧美激情| 欧美性猛交美女自慰91| 色哟哟 日韩精品| 成人A片男人的天堂| 探花一区二区三| 国产不卡的视频| 欧美操人| 国产一级137片内射麻豆| 97超级色碰碰| 中文字幕五区| 亚洲精品成人动漫在线| 加勒比无码毛片| 天天色香欲综合网| 午夜激情成人在线观看| 欧美久久人体| 啊嗯好大视频在线观看| 国产精品成人蜜臀AV在线| 欧美成人精品一区| 黄色不卡视频| 国产农村一一级特黄毛片| 另类图片综合| 欧美丝袜美女电影一二三四区| 久久久五月天| 日韩精品第3页| 97爱免费插| 超碰久久性爱| 3028国产精品| 91综合色噜噜| 97视频在线免费| 日本天堂网| 免費黃色視頻觀看一| 26uuu最新| 青青草一区二区三区四| 任我爽视频在线观看| 操逼逼福利视频| 精品国产Av无码久久久伦古装| 国产精品亚洲色婷婷久久久| 夜夜夜夜久久久久| 91熟女少妇| 欧美日韩黄色片一区二区三区四区人与兽做爱| 中文字幕 国产区| 亚洲男人久久综合天堂| 久久伊人影院| 九九九九九九精品| 加勒比伊人综合| 麻豆福利视频导航| 中文字幕亚韩| 肉嘟嘟www视频在线观看高清| 欧美日韩大陆黑人少妇99| 91oumei| 岛国小电影| 97欧美精品综合| 久久伊人青青草| 97色伦欧美| 日韩无码专区| 亚洲九月丁香| 国产精品宅男免费| 国产精品探花色| 色综合一本| 欧美色图91| 四季av一区二区凹凸精品小说| 久久久九九九九| 欧美一区二区传媒| 1024亚洲中文字幕久在线看片你懂的 | 亚欧性爱无码| 久久无码成人| WWW啪啪的com| 久久精品中文字幕无码l| 欧美日韩国产另类综合| 无遮挡一级毛片视频免费的| 十八禁视频一区二区| 日本黄大片在线观看视频| 色色毛片| 国产第12页| 亚洲成aⅴ人片不卡无码| 午夜成人爽爽爽爽A片李冰冰| 国产精品午夜AV完会免费| 97爱综合| 国产亚洲日韩欧| 国产不良强奸视频免费看| 超碰人人操97碰| 欧美偷拍区| 欧美性爱1080p| 屁屁影院一区二区三区国产 | 日韩伦理视频| 国产成自自拍在线观看| 香蕉免费一区二区三区不读| 欧美综合自拍亚洲综合图| 国产精品午夜成人福利| 亚洲精品影视老司机| 久久成年精品| 久久专区| 久久久久久中文版| 啊啊啊要高潮了| 99久久精品无码一区二区毛片免费| 精品无码一区二区三区色欲| 天天色,天天干,天天干| 91在线精品| 丁香六月婷婷| 欧美A√综合网 | 国产多人在线观看视频| 少妇干B| 91超级碰碰碰| 日日干日日操五月天伦理视频| 蜜臀久久久| 中日韩久久久免费看| 92一区二区| 欧美日本中字另类在线| 天天干天天干天天干| 青青草视频导航官网| 激情文学小说一区二区| 婷婷色综合欧美日韩| 美女午夜福利免费视频| 久久成人东京热人妻| 天天操女人| 亚洲欧美综合| 嗯嗯啊啊用力视频免费| 欧美αv.com| 精品无码久久久久久久杏吧| 最新三级网址| 国产又粗又又黄又猛| 伊人国产视频| 激情综合网激情综合| 夜嗨影院| 亚洲五区熟女| 日本久久超碰| 入口操逼网站| 97综合国产精品高潮久久| 97se亚洲综合自| 国产亚洲精品美女久久久久久2021| 日韩乱码Av| 死我十八禁| 久久riav中文精品| 嗯嗯嗯,草死我| 密臀在线一区尤物| 91精品国产高清久久久久久,亚洲成人| 欧美性战999| 久久香蕉国产线看观看亚洲女人 | 日韩欧美被操黄免费观看| 男人精品区| 久久久成人国产精品无码| 日韩啪啪啪视频| 中国人高清www色视频免费| 99天堂网| 怡红院久久老司机| 日韩乱插| avav青青草久久夜| 日韩av影片在线观看| 好吊爽好吊爽在线视频,中文字幕精品一区二区日本,国产良妇出轨视频在线观看, | 国产精品久久久久久久久久久久久久久久| 91夜色| 五月天色图| 97操B| 强奸xx国产| 少妇精品久久久八区九区| 亚洲成人福利电影免费 | 日韩国产欧美伦理在线| 大吊色| 乱伦一二三区| 日日A∨| 嫩草在线视频| 99re6国产精品99re| 嫩草一区二区在线观看| 亚洲青青草| 成人性爱全视频观看| 亚洲综合 欧美| 久久久久亚洲Aⅴ无码| 亚洲国产青青| 国产伦乱91| 蜜区区视频79 | 欧美色爱综合| 亚洲激情网一二三四区| 操逼操逼操| 人人爽夜夜操| 久久久国产亚洲精品系列| 操屄不卡视频| 午夜操一视频一区| 69超碰综合| 国产精品高潮久久久无码| 亚洲视频,小说| 嫩草影院在线观看精品| 男人的天堂VA| 午夜久久一区二区无码中出| 黄色人人| 欧美色图99| 精品久久久九九九孕妇| 强奸乱伦AV网址| 人妻熟女一区二区| 99精品在线观看| 自拍内地三级在线观看| 蜜臀av网址| 精品久久久久久亚洲| 欧美性爱日韩高清| 四虎影视永久在线观看精品免费网站| 92福利社视频| 乱伦1色页| 亚洲视频精选| 青青欧洲黑| 五月综合视频| 涩涩涩综合| 后入国产| 啊啊啊啊啊啊啊在线| 蜜臀久久一区二区| 精品成人动漫一区二区| 福利视频网站| 亚洲日韩东京热一区| 情色日播放AV| 操逼网免费无码视频| 97精品久久| 日韩色图 一区二区| 97欧美精品综合| 久久艹逼视频| 亚洲国产精品99久久久| 欧美国产婷婷久久| 91美女色视频亚洲| 激情自拍 校园春色| 日本一级二级三级网站| 综合亚洲欧美精品日韩?v| 四虎免费在线播放| 91超碰碰在线| 97se综合网| 嗯嗯啊中文字幕| 一区三区啪啪| 亚洲 自拍偷拍 欧美| 人人操人人色网| 亚洲第一页综合在线| 老司机免费视频在线91| 国产精品2020| 懂色AV一区二区三区| 中文字幕日本久久| www.91理论| 国产精品白丝在线播放| 久热一区二区| 亚洲 欧美 手机在线观看| 99精品视频在线观看免费| 天美传媒AV在线| 97超色| 熟妇熟女一区二三区| 91在线欧色| 内射夫妻三片| 久久久久女教师免费一区| 偷拍2020| 伊人久久蜜月| 久久久久国产| 伦在线97| 亚洲诱惑| 日韩天天本| 综合97亚洲| 日韩少妇在线视频| 精品久久久久久久久久久久| 欧美永久激情一区二区| 亚洲 欧美 另类 综合 偷拍| 中文字幕视频在线观看一区二区| 99无码| 超碰97 线线 在现| 啊啊啊啊啊好多水| 久久精品一区二区| 亚洲熟女诱惑| 久久国产精品m码| 不卡在线观看视频| 亚洲综合91| 青娱乐国产剧情av一区| 国产精品人妻免费精品| 爱妃国产亚洲视频中文字幕| 综合伊人激情| 国产精品免费日韩| 欧亚乱色熟女一区二区| 热99这里只有精品| 欧美国产日韩清纯唯美| 国产不卡片| 色情亚洲日本成人| 青青三级视频| 后入综合久久| 综合色一区三区二区| 免费AV中文网在线观看| 日韩高清黄片| 国产成人无码网站在线视频| 色五月激情网| 亚洲日韩av一区二区三区百合| 日本午夜福利视频| 色娱乐色呦呦夜夜夜夜av| 自拍第一页| 69一区二区三区| 午夜视频黄| 黄色小视频日本txt| 激情综合久久| 成人女人国产| 精品无码产区一区二| 91麻豆天美传媒在线| 日本成人免费一区二区三区| 尤物黄色在线观看网站| 大香蕉久| 97精品视频免费| 久久久性少妇| 欧美成年人性爱视频免费观看| 国产亚洲美日韩Aⅴ中文字幕无码成人| 亚洲最大无码中文字幕网站| 人妻夜夜爽天天爽麻豆三区网站 | 欧美最婬乱婬爆婬性视频 | 男人天堂毛片| 人人操人人插 - 百度 - 百度| 福利视频一区二区微拍| 亚洲夜色在线| 精品无码一区二区人妻久久蜜桃| 国产精品96久久久久久| 国产精品激情久久久久久久| 日韩素人无码一区二区三区三州| 很很很很操| 中文视频在线观看| 国产树林里野战在线看| 日本三级人妻a人妻一在线| 久久久久久久久国产| 九九九热| 色播综合| 久久久免费懂色| 人人爱人人乐人人操| 亚洲乱码尤物193YW| 9999伦理视频| 91九色丨风韵犹存| JIZZJIZZ国产精品喷水| 色综合加勒比四四季| 四虎影视精品| 亚洲精品日韩国产欧美| 免费看污网址| 色姑娘综合网| 婷婷久久综合| 90后后入| 国产 v乱码一区二| 日韩视频小说在线观看| 美女裸体无遮挡永久免费观看网站 | 麻豆黄色五月天| 91亚洲网站| 无码聚合| 欧美激情久久久久| 国产操伦| 你草精品在线视频| 亚洲成人精品在线一区| 亚洲情色电影网| 97在线视频免费看| 欧美黄色大香蕉一区二区| a人片中文字幕一区二区| 国产精品久久天天干| a片偷拍视频| 97精品国产97久久久| 男人的天堂一区| 99综合网| 阿姨一区二区免费视频-高清正片西瓜视频下载app-T450AV | 国产精品96| 女人爽到高潮久久久| 国产精品久久久亚洲第一牛牛_在线观看| 国产熟女完整版中字| 91色伦综合| 污污汅18禁网站在线永久免费观看| 五月天伊人| 日韩簧片免费看| 天天看特黄的免费网站| 99久久精品无码一区二区毛片免费| 欧美综合97www| 国产亚洲色停停久久99精品91| 伊人青青一区成人视频在线观看区| 国产精品 视频| 中文乱码99| 6080YYY午夜理论片在线观看| 日韩不卡码| 国产 日韩 欧美 中文 另类,国产 欧美 另类 制服 变态,高清 日韩 欧美 中文,高 | 久久久人妻| 无码heyzo高清一区| 18禁在线视频| 亚洲色图 图片| 色综合尤物| 亚洲se91| 精品美女在线视频| 乱伦图av| 久久9久久| 亚洲春色激情小说| 大香蕉视频一二三区| 亚洲视频二区 | 91九九九小逼| 日韩乱伦视频| www.男人的天堂| 打av高清| 欧美特大黄一级片片免费| 欧美亚洲今日在线| 国产av青草| 北约熟女超碰| 蜜臀久久99精品久久久久久成人小说 | 东北黄色电影| 欧美另类精品xxxx| 老女人综合| 人妻在线大香蕉| av一区二区三区 中文| 久久久久久九九九九| 97视频在线观看高清资源| 蜜乳AV一区二区三区四| 久热热| 日韩中文字幕2020| 成人精品在线| 为用户提供免费看黄网址在线观看| 九99久久| 日日日啊啊啊| 97人人超| 99久久精品无码一区二区毛片免费 | 欧美韩国你懂得在线| 激情综合五| 思思热免费在线视频| 97国产精品一区| 超碰98综合网| 嗯啊啊啊轻点视频| 国产精品无码AV网站| 97超碰人人模人人拍人人| 久艹视频在线| 欧美成人色| 婷婷香蕉欧美在线一区二区三区 | 亚州色图狠狠干| 99在线精品观看99| 多毛小伙内射老太婆| 日韩精品人妻| 欧中美三级一区二区三区| 午夜福利区| 国产乱码久久| 日本三级日本三级99| 精品人妻一区二区视频| 精品欧美老熟女一二区| av橘色网站| 日韩资源网| 97爱亚洲综合色| 欧美视频在线第3页| 久久东京国产精品视频| 日韩欧美tv一区二区在线观看| www.av家庭乱伦| 不卡视频一区蜜桃视频 | 亚洲中字幕日本一区二区三区| 加勒比无码毛片| 色九九综合AV| 成熟熟女国产精品一区二区| 91色黑人少妇| 久久亚洲骚逼综合| 亚州伊人色综台| 成人看片网站| 人妻中文在线| 色色色色网站| 亚洲成A∨人影院在线欢看| 亚洲欧美日韩免费电影| 超碰国产精品无码| 亚洲人体视频在线观看| 日本中文字幕不卡视频| 婷婷综合伊人一区| 中文字幕乱码在线观看| 日韩无码第3页| 亚洲精品97久久中文字幕| 999九九九九国产动| 国产偷人妻精品一区二区在线| 欧美久久久15P| 99www.bibizy香蕉资源国产一区二区三区高清 | www.91逼逼.com| 视频在线观看免费一区二区三区 | 91是天天| 国产a级精品| 99操| av东京热男人的天堂| 亚洲视频二区| 色777999综合| 亚洲日精品| 午夜噜噜噜| 人妻精品一区二区| 国产免费一区2区3区| 日韩免费中文字幕视频| 日韩免费福利在线观看| 国产乱色国产精品免费视| 久草网站免费在线观看| 怡红院一区二区熟女人妻| 午夜男人一级A片7777| 色99视频| 嗯嗯啊啊操死我| 久久久久亚洲精品| 丰满人妻一区二区中文| 青青草影视蜜久久| 久久久四区| 人人爱人人乐人人操| 在线综合 亚洲 欧美中文字幕| 国产专区第一页| 欧美特大黄一级片片免费| 久久女婷| 青青草吊丝| 视频二区熟女人妻| 9久久久久| 人人摸.人人色| 在线啊v一区| 日本熟妇熟色97一本在线观看| 日本丝袜美腿人妻九九| 物业黑人 AV一区| 亚洲人久久久久日| 国产91av在线播放| 婷婷色影院| 极品粉嫩一区二区| 无码人妻丰满熟妇区毛片| 蜜臀视频网站| 91快色色色色色| 激情一区二区三区在线观看| 蜜臀99999| 96超碰网| 蜜乳AV.COM| 开心五月激情网| 精品性爱久久视频| 麻豆成人影音在线| www.99中文字幕| 五月婷婷综合网| 男人的天堂无码| 日本影视久久免费| 免费A V在线播放| 嗯啊不要啊啊在线观看视频| 超碰97综合网| 波多野结衣一级视频| 国产精品一二三免费网站| 欧美韩日精品资源| 97碰| 日韩999| 大香蕉之青青草原| 色吧5亚洲| 黄色AV影视| 国产超碰欧美| 欧美操逼熟女| 亚洲 欧美 另类 综合 偷拍| 黄色工厂这里只有精品| 亚洲成人福利电影免费| 欧美日韩理论一区| 外国免费性情大片| 黄色小视频日本txt| 97久久精品国产| 亚洲色图 欧美| 激情丁香五月婷婷| 婷婷九月丁香| 国产区91柔拿会所技师| 无码人妻丰满熟妇奶水区毛片| 草草草草视频| 激情丁香婷婷| 女人18精品一区二区三区| 最新亚洲人成网站在线影院| 黄色成品网站| 91社区伊人| 美女尤物福利视频| 狠狠爱夜夜| 91日韩在线| 新91视频.cmp| 国产成人精品亚洲日本| 97视频在线观看网站| 熟女乱伦A| 精品一区二区三区四区外站 | 国产剧情一区在线观看| 欧美熟妇精品黑人巨大91| 亚洲天堂 视频你懂的| 极品色电影院| 国产精品久久久久中文字幕| 加勒比AV天堂| 亚洲av影音先锋| 一区二区国产视频在线观看| 精品欧美А∨无码黑人大荫蒂| 99九九久久| 久久久久亚洲AV无码专区少妇| 欧美亚洲AN| 伊人久久在线视频观看| 午夜后入| 91强热人妻| 美女上床网站| 久操热线| 久久色精品视频在线| 精品四五区| 成人午夜高潮av猛片| 美女大乳久久久久久久女人18| 91性高朝久久久久久久久| 亚洲欧洲无码97久久精品| 曰韩操B| 99热国产| 九九亚洲视频| 亚洲激情视频| 欧美欲色| 中日亚韩免费视频| 少妇精品久久久八区九区| 静品嫩模一区二区| 蜜臀久久99精品久久久久久酒店| 资源在线观一 二| 亚洲美女AV无码| 亚洲91网站| 丰满人妻av一区二区三区| 96久久久久久久| 亚洲人在线| 在线综合色| 精品国产乱码久久久A| 天堂日本亚洲欧美| 国产操伦| www.人人摸在线视频| 欧美精品另类人妖xxxx| 午夜激情成人在线观看| 安微少妇操BBB| 欧美综合骚| 国产精品国产自产高清AV| 超碰97.com| 极品五月天噜噜| 人妻81p| 一起草视频在线| 91中文精品日韩欧美在线 | 放黄片放3级黄片没穿衣服| 一本一首道人妻少妇免费久久| 综合久久欧美| 中国AAAAAA黄色片| 国产超碰欧美| oumeisetupian| 91一起操| 性影在线视频| 天天肏天天干| 加勒比中文av| 亚洲日韩美国人妻| 久9久| 七月丁香婷婷| 五月香婷婷| 久久久9 9 9精品| 黑人狂躁日本妞一区二区三区| 欧美后进式| 夜夜高潮夜夜爽夜夜爱爱一区| 久操不卡视频| 日韩人妻无码精品系列| 精品一区二区亚洲国产| AV色五月| 日韩精品99久久久久久中文字幕 | 国产亚洲精品第一最新| 强被迫伦姧在线观看无码网站| 97伦综合| 北野未奈加勒比av| 淫骚熟女一区二区三区| 91久精品| 日韩啪啪啪啪啪| 久久精品性| 久久久久久国产精品免费网站| 亚洲春色一区二区三区| 超碰色老头| 新怡红院| 人妻人久久精品中文字幕| 中文久久96| 精品176精品2| 欧美久久久15P| 蜜桃传媒一区二区亚洲| 亚洲av在线免费观看| 婷婷综合久久| 久热9| 丰满人妻大屁一区二区| 99re公开精品免费视频| 人妻精品一区二区三区| 久久久影院| 国产久久一区二区午夜| 天天爱天天操| 97色色色| 综合婷婷| 激情综合五月| 一级黄色影片| 少妇一线天久久久久久| 亚洲天堂热| 久热婷婷| 婷婷五月天补不补| 99国产人成精品| 校园春色之综合网| 久九干| 精爱久久| 九九热在线精品视频| 国产情色在线| 免费国产| 亚洲综合伊人无码久久|