精品欧美一区二区三区在线观看 _久久久久国色av免费观看性色_国产精品久久在线观看_亚洲第一综合网站_91精品又粗又猛又爽_小泽玛利亚一区二区免费_91亚洲精品国偷拍自产在线观看 _久久精品视频在线播放_美女精品久久久_欧美日韩国产成人在线

抖音 Android 包體積優化探索:基于 ReDex 的 DEX 優化落地實踐

原創 精選
移動開發 移動應用
抖音是字節跳動規模最大、運行環境復雜度最高的應用之一。在 ReDex 落地初期,由于對復雜度估計不足,在獨立灰度和全量灰度期間引起了一些問題,在解決問題的過程中,我們也逐步形成了一套迭代流程以保證優化的穩定性。

作者 | 馮瑞;廖斌斌;劉豐愷

前言

應用安裝包的體積會顯著影響應用的下載速度和安裝速度,按照 Google 的經驗數據,包體積每增加 1M 會造成 0.17%的新增折損。抖音的一些實驗也證明了包體積會顯著影響下載激活的轉化率。

Android 的安裝包是 APK 格式的,在抖音的安裝包中 DEX 的體積占比達到了 40%以上,所以針對 DEX 的體積優化是一種行之有效的包體積優化手段。

DEX 本質上是由 Java/Kotlin 代碼編譯而成的字節碼,因此,針對字節碼進行業務無感的通用優化成為我們的一個探索方向。

優化結果

終端基礎技術團隊和抖音基礎技術團隊在過去的一年里,利用 ReDex 在抖音包體積優化方面取得了一些明顯的收益,這些優化也被同步到了其他各大 App 上。

在抖音、頭條和其他應用上,我們的優化對 APK 體積的縮減普遍達到了 4%以上,對 DEX 體積的縮減則可以達到 8% ~ 10%

優化思路

在 android 應用的構建過程中,Java/Kotlin 代碼會先被編譯成 Class 字節碼,在這個階段 gradle 提供了 Transformer 可以進行字節碼的自定義處理,很多插件都是在這個階段處理字節碼的。然后,Class 文件經過 dexBuilder/mergeDex 等任務的處理會生成 DEX 文件,并最終被打進安裝包中。整個過程如下所示:

所以,針對字節碼的優化是有 2 個時機可以進行的:

  • 在 transformer 階段對 Class 字節碼進行優化
  • 在 DEX 階段對 DEX 文件進行優化

顯然,對 DEX 進行優化是更理想的一種方式,因為在 DEX 文件中,除了字節碼指令外,還存在跨 DEX 引用、字符串池這樣的結構,針對這些 DEX 格式的優化是無法在 transformer 階段進行的。

在確定了針對 DEX 文件進行優化的思路后,我們選擇了 facebook 的開源框架 ReDex 作為優化工具,并對其進行了定制開發。

選擇 ReDex 的原因是它提供了豐富的基礎能力,ReDex 的基礎能力包括:

  1. 讀寫及解析 DEX 的能力,同時可以在一定程度上讀取并解析 xml 和 so 文件
  2. 解析簡單的 proguard keep 規則并匹配類/方法/成員變量的能力
  3. 對字節碼進行數據流分析的能力,提供了常用的數據流分析算法
  4. 對字節碼進行合法性校驗的能力,包括寄存器檢查、類型檢查等
  5. 一系列的字節碼優化項,每項優化稱為一個 pass,多個 pass 組成 pipeline 對 DEX 進行優化

我們基于這些能力進行了定制和擴展,并期望最終建立完善的優化體系。

優化項

在抖音落地的優化項,包括 facebook 開源的優化和我們自研的優化,從其出發點來看,可以大致分為下面幾種:

  • 通用字節碼優化:通常意義下的編譯優化,如常量傳播、內聯等,一般也可在 Transformer 階段實現
  • DEX 格式優化:DEX 中除了字節碼指令外,還包括字符串池、類/方法引用、debug 信息等等,針對這些方面的優化歸類為 DEX 格式優化
  • 針對編程語言的優化:Java/Kotlin 的一些語法糖會生成大量字節碼,可以對這些字節碼進行針對性的分析和優化
  • 提升壓縮率的優化:將 DEX 打包成 APK 實質上是個壓縮的過程,對 DEX 內容進行針對性的優化可以提升壓縮率,從而產生體積更小的 APK

這幾種優化沒有明確的標準和界線,有時一個 Pass 會涉及到多種,下面詳細介紹一下各項優化。

通用字節碼優化

ConstantPropagationPass

該 Pass 實際上包含了常量折疊和常量傳播。

常量折疊是在編譯期簡化常量的過程,比如

y = 7 - 14 / 2
--->
y = 0

常量傳播是在編譯期替代指令中已知常量的過程,比如

int x = 14;
int y = 7 - x / 2;
return y * (28 / x + 2);
--->
int x = 14;
int y = 7 - 14 / 2;
return (7 - 14 / 2) * (28 / 14 + 2);

上面的例子經過 常量折疊 + 常量傳播優化后就會簡化為

int x = 14;
int y = 0;
return 0;

再經過死代碼刪除就可以最終變為return 0。

具體的優化過程是:

  1. 對方法進行數據流分析,主要針對 const/move 等指令,得出一個寄存器在某個位置可能的取值
  2. 根據分析的結果,進行指令替換或指令刪除,包括:
  • 如果值肯定是非空的,可以將對應的判空去掉,比如 kotlin 生成的 null check 調用
  • 如果值肯定為空,可以將指令替換為拋空異常
  • 如果值肯定讓某 if 分支走不到,可以刪除對應的分支
  • 如果值是固定的,可以用 const 指令替換對應的賦值或計算指令

一個方法經過 ConstantPropagationPass 優化后,可能會產生一些死代碼,比如例子中的int y = 0,這也為后續的死代碼刪除創造了條件。

AnnoKillPass

該 Pass 是用來移除無用注解的。注解主要分為三種類型:

  • SOURCE:java 源碼編譯為 class 字節碼就不可見,此類注解一般不用過于關注
  • CLASS:字節碼通過 dx 工具轉成 DEX 就不可見,代碼運行時不需要獲取信息,所以一般來說也不需要關注,實測發現部分注解仍然存在于 DEX 中,這部分注解可以進行優化
  • RUNTIME:DEX 中仍然可見,代碼運行中可以通過 getAnnotations 等接口獲取注解信息,但是隨著業務的迭代,可能獲取注解信息的代碼已經去掉,注解卻沒有下掉,這部分注解會被 ReDex 安全的移除

除此之外,實際上為了支持某些系統特性,編譯器會自動生成系統注解,雖然注解本身是 RUNTIME 類型,但是可見性是VISIBILITY_SYSTEM

  • AnnotationDefault : 默認注解,不能刪除
  • EnclosingClass : 當前內部類申明時所在的類
  • EnclosingMethod : 當前內部類申明時所在的方法
  • InnerClass : 當前內部類名稱
  • MemberClasses : 當前類的所有內部類列表
  • MethodParameters : 方法參數
  • Signature : 泛型相關
  • Throws : 異常相關

舉例說明

編譯器生成 1MainApplication$1這個匿名內部類,帶有 EnclosingMethod 和 InnerClass 注解

系統提供以下接口獲取類相關的信息,就是通過分析相關的系統注解來實現的

  • Class.getEnclosingMethod
  • Class.getSimpleName
  • Class.isAnonymousClass
  • ....

如果代碼中不存在使用這些接口獲取類信息的邏輯,就可以安全的移除這部分注解,從而達到縮減包大小的目的。

RenameClassesPass

該 Pass 通過縮減類名的字符串長度來減小包體積

比如把類名從La/b/c/d/e;改為LX/a;,可以類名字符串的長度,從而達到包大小縮減的目的。實際上 Proguard 本身已經提供類似的功能: -repackageclasses 'X',效果如下:

但是-repackageclasses 'X'的處理會影響 ReDex 的 InterDexPass 的算法邏輯(InterDexPass 可以參考下文),導致收益縮減

  • 收益測試
  • Proguard-repackageclasses 'X' 收益: 600K+
  • RedexInterDexPass 收益: 400K+
  • 同時應用 Proguard-repackageclasses 'X'? 和 RedexInterDexPass 收益: 40K+

本質原因在于 Proguard 重命名后,影響了 InterDexPass 函數引用權重分配,導致 InterDex 收益被回收

  • 解決方案
  • InterDexPass 深入分析原理,優化權重算法
  • 先執行 InterDexPass,后執行類似 Proguard 的-repackageclasses 'X'

權重算法優化相對來說比較復雜,同時存在眾多不可確定性,比如潛在的跟其他優化的沖突,所以我們采取了第二種解決方案。

這里需要解決的一個關鍵點在于如何確定一個類名是否可以被安全的重命名,我們采取了一個比較取巧的方式,ReDex 會分析 Proguard 傳遞上來 mapping.txt 文件,只要我們保持跟 Proguard 類重命名優化一樣的處理策略,就不會引發反射/native 調用/序列化等一系列問題。

但是執行起來還是碰到各種千奇百怪的問題,比如 Signature 系統注解失效問題。Signature 注解的內容是非標準的類名格式,所以類重命名后簡單回寫字符串或者更新 Type 類型會導致 Signature 注解失效,最后通過深入解析 Signature 格式規避了這個問題。

StringBuilderOutlinerPass

該 Pass 是針對 StringBuilder 的 CallSites 進行分析縮略的優化,與死代碼刪除搭配使用可以有不錯的優化效果。

為何要優化 StringBuilder 呢?在 Java 的代碼開發過程中,字符串操作幾乎是我們最經常做的一件事情,無論是實際處理字符串拼接還是各種不同數據類型之間的拼接操作。而這些拼接操作都會被 Java 的 de-sugar 優化為 StringBuilder 操作。比如:var log = "A" + 1 + "B" + 1.0f + other_var; 會被優化為:

StringBuilder builder = new StringBuilder();
builder.append("A"); builder.append(1);
builder.append("B"); builder.append(1.0f);
builder.append(other_var);
builder.toString();

因此我們對 StringBuilder 的所有 Callsites 進行分析,在最好情況下多個方法調用可以被優化為一個調用,這個方法是一個 outline (外聯)方法,具體的參數拼接和 toString 被隱藏在函數內部:

invoke-static {v1, v2, v3} Outline;.bind:([Ljava/lang/Object)Ljava/lang/String;

優化步驟可以被簡單的分為如下幾個步驟:

  1. 生成一個泛型的外聯方法、以及數個特定參數的方法:我們可以認為生成的方法大概是這樣的
@Keep
public static String bind(Object... args) {
StringBuilder builder = new StringBuilder();
for (int i = 0; i < args.length ; i++) {
builder.append(args[i]);
}
return builder.toString();
}
  1. 收集StringBuilder 的 CallSites :通過抽象解釋和不動點分析,分析所有的 StringBuilder 操作,對 append、new-instance、和 init 方法分類。判斷每次 append 的參數是不是 immutable 操作,如果增加的 insn 少于減少的 insn 即會減少代碼,就對這里進行處理。
  2. 生成外聯方法調用:由于我們使用了泛型方法來接受參數,因此我們要對基礎類型生成 ValueOf 的轉換操作、并且刪除append 方法前為了防止被錯誤優化我們還需要插入 move 指令來 copy 原有參數(這些 move 指令會被后續優化正確刪除)、如果參數個數還在我們生成的特定 outline 方法范圍內我們就可以使用特定方法來生成外聯函數,其余的將使用泛化的外聯來接受。

DEX 格式優化

InterDexPass

該 Pass 是針對跨 DEX 引用的優化。

跨 DEX 引用是指當一個 DEX 需要“使用”到另一個 DEX 中的類/方法/變量時,需要在本 DEX 中保存一份對應的類/方法/變量的 id,如果 2 個 DEX 用到了相同的字符串,那么這個字符串在 2 個 DEX 都需要進行定義。所以,改變類/方法/變量和字符串在 DEX 中的分布,可以減小引用的數量,從而減小 DEX 的體積。從原理中也可以看出,該優化對單 DEX 的應用是無效的。

從上圖可以看到,進行類重排后,DEX0 的類引用和方法引用數量都減少了,DEX 的體積也會因此減小。

具體的優化過程是:

  1. 收集每個類涉及的所有引用,按照引用數量和類型計算出類的權重
  2. 根據權重計算出每個類的優先級
  3. 根據優先級選取一個類放入 DEX 中,然后調整剩余類的優先級,重復此步驟直到所有類都被處理

ReBindRefsPass

該 Pass 是針對方法引用的優化,其原理同 InterDexPass。

在字節碼中,invoke-virtual/interface指令需要一個方法引用,在很多情況下,這個引用指向的是子類或者實現類的引用,把這個引用替換成父類和接口的方法引用不會影響運行時邏輯,同時會減少 DEX 中方法引用的數量。在生成 DEX 的時候,方法引用的 65536 限制通常是最先遇到的瓶頸,該優化也可以緩解這種情況。

如上圖所示,優化前 caller 方法的 invoke 指令使用的是子類引用,其偽指令如下所示,需要用到 2 個引用

new-instance v0, Sub1
invoke-virtual v0, Sub1.a()
new-instance v1, Sub2
invoke-virtual v1, Sub2.a()

優化后,invoke 指令都指向其父類應用,2 個引用可以合并為 1 個,減少了 DEX 中的引用數量

new-instance v0, Sub1
invoke-virtual v0, Base.a()
new-instance v1, Sub2
invoke-virtual v1, Base.a()

針對編程語言的優化

KotlinDataClassPass

該 Pass 是對 Kotlin data class 的優化,基本思路是對 data class 的生成代碼進行精簡。

解構聲明優化

Kotlin 中存在解構聲明這種語法,可以更方便的創建多個變量,基本用法如下

data class Person(val name: String,val age: Int)
val (name,age) = person("John",20)

kotlinc 會為Person類生成 get 方法和 componentN 方法,如下是偽代碼表示

Person {
String name;
Int age;

getName(): String { return name; }
getAge(): Int { return age; }
component1(): String { return name; }
component2(): Int { return age; }
}

// 解構聲明編譯為
val name = person.component12 1()
val age = person.component2()

可以看到,get 和 component 的邏輯是一樣的,所以在編譯期,可以進行全局的匹配,用 get 替換掉 component,然后再刪除 component。

toString 等生成方法優化

kotlin compiler 為 data class 生成的 toString 具有相似的代碼結構,因此可以生成一個輔助方法,然后在所有 data class 的 toString 方法中調用這個輔助方法,即外聯,從而減少指令數量。

equals 和 hashCode 也可以進行類似優化,但是風險相對較高,因此單獨為這些優化配置了開關,業務方可以視情況開啟。

提升壓縮率的優化

RegAllocPass

DEX 及其他文件經過壓縮打成 APK,如果能通過改變 DEX 的內容來提升壓縮率,那么也會減小最終的包體積。RegAllocPass 就是通過重新分配寄存器來提升壓縮率的。

dx 生成 DEX 時使用的是線性寄存器分配算法,其基本步驟是進行存活變量分析,然后計算出每個變量的活躍區間,再根據活躍區間依次為變量分配寄存器,超出活躍區間的寄存器可以進行再分配,其優點是運行速度快,但結果往往不是最優的。

比如下面的代碼,dx 分配了 6 個寄存器,v0 ~ v5

public static double calculateLuminance(@ColorInt int color) {
final double[] result = getTempDouble3Array();
colorToXYZ(color,result);
return result[1] / 100;
}

相對的,ReDex 使用了圖著色算法進行寄存器分配,基本步驟是進行存活變量分析,并構建沖突圖,沖突圖的每個節點是一個變量,如果 2 個變量可以同時存活,就在兩個節點之間建立邊,最后為沖突圖著色,每個顏色代表一個寄存器,著色完成即寄存器分配完成。著色法相對更慢,結果一般更優。對上面同樣的代碼,著色法使用了 4 個寄存器,v0 ~ v3。

DEX 中的方法使用的寄存器越少,其內容重復率就越高,壓縮率也會更大,從而減小了包體積。

抖音落地

抖音是字節跳動規模最大、運行環境復雜度最高的應用之一。在 ReDex 落地初期,由于對復雜度估計不足,在獨立灰度和全量灰度期間引起了一些問題,在解決問題的過程中,我們也逐步形成了一套迭代流程以保證優化的穩定性。下面介紹一下我們遇到過的典型問題及當前的迭代流程。

遇到的問題

兼容性問題

一般來說,只要按照字節碼規范進行優化,就不會有兼容性問題,因為 dalvik/art 也是按照規范去校驗和運行字節碼的,即使進行了錯誤的優化,引起的問題也應該是共性問題。但很多事都有例外,ReDex 就在某品牌手機的部分 Android 5.x 的機型上遇到了問題。

從 log 和一些 hook 來看,某品牌手機對 5.x 的 art 做了大量的魔改,可以推斷其魔改存在一些問題,導致對正確的字節碼的校驗和運行也可能出現問題。一個可能的原因是:在 ReDex 進行優化時,會對一些方法體的指令順序進行重排,這種重排是不影響方法的邏輯的,但是可能會改變一部分指令,魔改后的 art 在校驗這樣的方法時可能會報 verify error,引起 crash。

最終通過黑名單配置跳過了這些方法的優化規避了問題,在后續的優化過程中,沒有再遇到類似的問題。

復雜場景優化問題

抖音業務復雜,代碼寫法多樣,給靜態分析和優化增加了一些難度,也更容易遇到問題。下面是 2 個典型問題:

1.空方法優化問題 代碼中可能存在一些空方法,排除掉反射和 natvie 調用等場景后,剩下的空方法應該是可以刪除的。但是在做優化時,卻遇到了 crash,如以下代碼

object XXXSDKHelper {
init {
initXXXSDK()
}
fun fakeInit() {
}
}

// 初始化任務
public class XXInitTask implements Runnable {
@Override
public void run() {
XXXSDKHelper.INSTANCE.fakeInit();
}
}

在初始化代碼中調用fakeInit,它是一個空方法,調用它的目的是觸發XXSDKHelper類加載從而執行init語句塊,如果刪除了這個空方法,就會導致初始化未執行,在后續的流程中拋空指針。

2.復雜反射問題

對于 Class.forname(...)等簡單的反射用法,靜態分析是可以分析出來的,但是對一些經過字符串拼接或者嵌套之后的反射,靜態分析很難分析到。因此,對可能會被反射的代碼進行優化需要非常小心,通常來說,匿名內部類是不會通過反射調用的,基于此前提,我們進行了匿名內部類的重命名優化,但是在灰度后,發現某些第三方 SDK 會通過復雜的運行時邏輯對匿名內部類進行了反射調用,最終導致了 ClassNotFoundError。

復雜場景的優化問題有些是業務代碼不規范造成的,但更多的是優化前提(空方法可以刪除/匿名內部類不會被反射)不成立所導致,所以在進行優化時首先需要對假設進行謹慎的驗證。

迭代流程

為了減少穩定性問題,我們總結了 ReDex Pass 的迭代流程。

在對一項 Pass 有了初步構思后,組內會進行可行性討論,如果理論上可行就進入開發和驗證階段,之后同步進行至少 2 輪的獨立灰度驗證和業務方 Pass 評審,最后進行全量灰度驗證。其中任意一個環節發現問題,都會重新進行整個流程。

通過這個流程,我們大大減少了穩定性問題遺留到灰度階段的可能,在不斷完善迭代流程的同時我們也在探索通過加強單元測試、自動化測試等方式來提升質量。

后續規劃

ReDex 仍然在持續迭代中,未來我們會在以下幾個方向繼續進行深入探索:

  1. 更多包體積優化的探索和迭代,同時探索字節碼優化在性能提升方面的可能性
  2. 提升字節碼質量
  • 更加嚴格的合法性校驗;ReDex 之前已經檢測出若干自定義插件和 proguard 的問題,將問題攔截在了編譯期,后續會繼續提升該能力
  • 建立更加完善的質量驗證體系;ReDex 作為編譯期的全局字節碼優化方案,如果保證優化后的字節碼質量一直是個痛點,我們會繼續在單元測試、自動化測試等方向探索質量提升的手段
  1. 增加編譯期監控,更加快速便捷的解決編譯期字節碼問題,提升接入體驗
  2. 其他應用方向探索;如方法插樁、某些條件下的死代碼掃描等。
責任編輯:未麗燕 來源: 字節跳動技術團隊
相關推薦

2022-05-07 15:51:47

Android資源文件文件名

2022-03-29 13:27:22

Android優化APP

2022-06-06 12:19:08

抖音功耗優化Android 應用

2024-06-13 17:10:16

2022-06-07 15:33:51

Android優化實踐

2023-07-19 22:17:21

Android資源優化

2025-07-30 09:36:47

2023-11-03 17:02:18

抖音直播畫質優化

2022-07-19 16:47:53

Android抖音

2023-03-03 15:43:23

抖音世界杯畫質優化

2022-07-06 13:02:00

高延時電商直播主播互動

2022-04-28 15:07:41

抖音內存泄漏Android

2022-10-28 13:41:51

字節SDK監控

2024-11-13 08:47:24

2022-08-26 16:24:19

抖音體系化建設項目

2023-04-14 15:31:55

SwiftToolchain

2013-03-27 09:17:17

Android開發AndroidList

2022-04-28 09:36:47

Redis內存結構內存管理

2022-08-31 14:42:32

抖音包體積特效中臺
點贊
收藏

51CTO技術棧公眾號

波多野结衣xxxx| 国产精品区一区二区三在线播放| 亚洲av熟女国产一区二区性色| 国产精品第一国产精品| 亚洲精品成人天堂一二三| 成人在线观看网址| 国产精品suv一区| 香港欧美日韩三级黄色一级电影网站| 欧美成人r级一区二区三区| 精品久久一二三| 在线观看完整版免费| 成人网在线播放| 国产精品久久久久999| 1024手机在线视频| 久操国产精品| 日韩精品一区二区三区老鸭窝| 男人透女人免费视频| 婷婷在线播放| 亚洲国产精品成人综合| 国产精品免费一区二区三区在线观看 | 国产一区二区三区毛片| 男人午夜视频在线观看| 超碰在线视屏| 亚洲免费观看高清| 日本精品一区二区| 色综合视频在线| 久久精品二区亚洲w码| 香蕉久久精品| 色婷婷综合激情| 日本久久久网站| 2021av在线| 久久久久国产精品麻豆ai换脸 | 亚洲一区二区三区在线免费| 在线观看免费一区| 欧美 日韩 亚洲 一区| 国产激情视频在线观看| 国产清纯白嫩初高生在线观看91| 成人高清在线观看| 国产又粗又黄又爽视频| 日本在线不卡一区| 91成人天堂久久成人| 蜜桃麻豆91| 午夜影院在线视频| www.亚洲精品| 精品一区日韩成人| 欧日韩在线视频| 国产大陆精品国产| 91网站在线免费观看| 亚洲一区 中文字幕| 奇米888四色在线精品| 日本午夜在线亚洲.国产| 国产一卡二卡在线| 亚洲网站视频| 午夜精品一区二区三区在线 | 欧美性受xxxx黑人| 国产尤物久久久| 一区二区三区在线播放欧美| 精品无码国产污污污免费网站| 综合色就爱涩涩涩综合婷婷| 亚洲国产天堂久久国产91| 东京热av一区| 青青一区二区| 亚洲天堂男人天堂| 我不卡一区二区| 久久中文字幕av一区二区不卡| 在线播放日韩精品| 青青青手机在线视频| 99久久婷婷这里只有精品| www国产亚洲精品久久网站| 三级黄色录像视频| 欧美精品播放| 欧美激情国内偷拍| 丰满少妇乱子伦精品看片| 一区二区日韩免费看| 2021国产精品视频| 亚洲第一网站在线观看| 久久国产日韩欧美精品| 91久久久精品| 亚洲a视频在线| 91丨九色丨国产丨porny| 色视频一区二区三区| 黄色网页在线观看| 亚洲图片有声小说| 男人靠女人免费视频网站| 精品网站在线| 欧美一区二区视频在线观看2022| 伊人成人免费视频| 欧美色图五月天| 中文字幕视频一区二区在线有码| 紧身裙女教师波多野结衣| 亚洲免费激情| 国产精品无码专区在线观看| 国产成人三级在线播放 | 欧美一级搡bbbb搡bbbb| 成熟妇人a片免费看网站| 欧美午夜精品一区二区三区电影| 不卡av在线网站| 五月天激情国产综合婷婷婷| 麻豆一区二区三区| 高清av免费一区中文字幕| 你懂的免费在线观看| 亚洲欧洲日韩av| 黄色大片中文字幕| 亚洲精品乱码日韩| 亚洲国产精品人久久电影| 国产日韩精品中文字无码| 国产精品黄色| 国产狼人综合免费视频| 天堂中文网在线| 国产精品国产三级国产普通话三级| 免费视频爱爱太爽了| 中韩乱幕日产无线码一区| 日韩女优视频免费观看| 亚洲一区视频在线播放| 欧美日本中文| 成人国产亚洲精品a区天堂华泰| 五月婷婷六月色| 亚洲精品第1页| 福利片一区二区三区| 亚洲v天堂v手机在线| 欧美黑人xxxx| 国产熟女一区二区三区四区| 国产欧美视频一区二区| 久久久久久久久久久视频| 日韩视频一二区| 中文字幕亚洲一区二区三区| caoporn国产| 99在线视频精品| 日韩一区二区高清视频| 亚洲人成777| 中文字幕一区二区三区电影| 无码视频在线观看| 26uuu久久天堂性欧美| 霍思燕三级露全乳照| 日韩一二三区| yellow中文字幕久久| 久久久国产免费| 国产三级久久久| 日韩av片在线看| 成人香蕉社区| 中国xxxx性xxxx产国| 乱亲女h秽乱长久久久| 久久69精品久久久久久国产越南| 中文字幕1区2区3区| 国产亚洲人成网站| 国模杨依粉嫩蝴蝶150p| 天堂成人娱乐在线视频免费播放网站 | 国内精品福利| 粉嫩精品一区二区三区在线观看 | 91av资源在线| 欧美在线观看视频在线| a级大片在线观看| 久久精品导航| 日本一区二区三区视频免费看| 2022成人影院| 国产一区二区日韩| 在线免费观看av网址| 国产午夜三级一区二区三| 国产日韩一区二区在线观看| 沈樵精品国产成av片| 国产精品都在这里| 91吃瓜网在线观看| 欧美精品xxxxbbbb| 亚洲国产成人精品综合99| 国产在线精品视频| 激情成人开心网| 加勒比色老久久爱综合网| 欧美一级高清免费播放| 理论视频在线| 在线不卡a资源高清| 五月婷婷一区二区| 成人高清视频免费观看| 日韩久久一级片| 日韩大片在线| 97久久精品午夜一区二区| xxxx成人| 在线观看视频99| a级片免费视频| 激情成人中文字幕| 91精品国自产在线| 国产成人精品免费在线| 成人在线免费观看av| 日韩精品黄色| 欧美顶级少妇做爰| 国产亚洲精品女人久久久久久| av爱爱亚洲一区| 手机看片福利日韩| 亚洲国产精品久久久久蝴蝶传媒| 国产精品一区二区三区免费观看| 成人免费网站视频| 久久久91精品国产| 天堂在线视频免费| 精品视频全国免费看| 青青草激情视频| 91一区在线观看| 最新免费av网址| 一本久道综合久久精品| 在线成人av电影| 麻豆一区二区| 国产在线一区二区三区| 182在线视频观看| 中文字幕亚洲综合久久筱田步美| 黄色美女一级片| 欧美午夜免费电影| 日韩久久久久久久久| 中文字幕永久在线不卡| 中文字幕无码人妻少妇免费| 久久精品国产色蜜蜜麻豆| 国产福利精品av综合导导航| 六月婷婷七月丁香| 精品一区二区三区的国产在线播放| 大西瓜av在线| 久久看人人摘| 欧美日韩精品一区| 高清日韩欧美| 成人黄色中文字幕| 成人免费无遮挡| 97免费中文视频在线观看| 天堂地址在线www| 亚洲人精品午夜在线观看| 午夜精品久久久久久久96蜜桃| 欧美性猛交xxxxxx富婆| 日韩一区二区视频在线| 一级日本不卡的影视| 亚洲a∨无码无在线观看| 久久这里只精品最新地址| 日本中文字幕精品| 精品一区二区在线观看| 激情内射人妻1区2区3区| 亚洲高清电影| 欧美另类videosbestsex日本| 成人在线免费视频观看| 欧美亚洲另类久久综合| 欧美绝顶高潮抽搐喷水合集| 成人欧美视频在线| 韩国三级大全久久网站| 国产欧美精品日韩精品| 日韩制服一区| 国产精品成久久久久三级| 在线毛片观看| 78色国产精品| jizz内谢中国亚洲jizz| 97在线观看视频| 美女搞黄视频在线观看| 久久久久久网址| 蜜桃传媒在线观看免费进入| 欧美巨乳在线观看| 黄色网址在线免费观看| 久久精品成人一区二区三区| 香蕉视频网站在线观看| 色老头一区二区三区| 欧美成年黄网站色视频| 久热在线中文字幕色999舞| 欧美成人二区| 精品中文字幕在线观看| 污视频网站在线免费| 欧美激情一区二区三级高清视频| 国产99re66在线视频| 高清一区二区三区四区五区| heyzo高清在线| 97人人做人人爱| 成人短视频app| 国产成人精品最新| 成人国产网站| 91香蕉电影院| 大桥未久女教师av一区二区| 国产一区二区三区四区五区在线 | av中文字幕一区| 老熟妇精品一区二区三区| 91色婷婷久久久久合中文| 国产精品扒开腿做爽爽| 国产精品理论片在线观看| 我要看黄色一级片| 一区二区不卡在线视频 午夜欧美不卡在| 久久成人在线观看| 亚洲a一区二区| 国产伦精品一区二区三区视频我| 欧美色图在线观看| a天堂在线视频| 日韩激情av在线播放| 久久久久久久久亚洲精品| 中文字幕日韩电影| 制服丝袜中文字幕在线| 69av视频在线播放| 99久久伊人| 国产经品一区二区| 欧美男同视频网| 在线观看欧美激情| 亚洲三级影院| 在线免费观看av的网站| 国产精品一级黄| av男人的天堂av| 亚洲乱码国产乱码精品精98午夜 | 在线视频91| 亚洲激情自拍| 久国产精品视频| 99国产精品一区| 91香蕉视频在线播放| 天天综合色天天综合色h| 亚洲天堂777| 日韩av综合网| 国产不卡在线| 情事1991在线| 91麻豆精品国产91久久久久推荐资源| 日本一区二区不卡高清更新| 欧美精品一卡| 亚洲欧洲日本精品| 97精品电影院| 欧美日韩一级大片| 欧美视频在线一区| 五月天婷婷在线播放| 久久成人在线视频| 成人精品电影在线| 国产偷久久久精品专区| 国家队第一季免费高清在线观看| 国产精品成人免费| 国产成人无码精品久久久久| 69av一区二区三区| 国产福利小视频在线观看| 午夜精品国产精品大乳美女| vam成人资源在线观看| 欧美日韩在线高清| 亚洲麻豆一区| 秋霞午夜鲁丝一区二区| 中文字幕日本乱码精品影院| 无码人妻黑人中文字幕| 亚洲国产毛片完整版| 亚洲综合影视| 亚洲精品女av网站| 97久久夜色精品国产| 中文字幕第21页| 91麻豆免费在线观看| 国产网站在线看| 欧美成人免费网站| 巨大荫蒂视频欧美大片| 国产美女被下药99| 日韩成人精品一区二区| 日本美女高潮视频| 国产日韩av一区| 日韩三级一区二区| 亚洲免费一在线| 中文字幕影音在线| 久久精精品视频| 亚洲一区日韩| 精品黑人一区二区三区观看时间| 午夜一区二区三区视频| 人妻精品一区一区三区蜜桃91| 欧美黄色免费网站| 91国内精品白嫩初高生| 日本国产中文字幕| 国产成人在线观看| 国产亚洲精品久久久久久无几年桃 | 97久久精品| av在线免费观看国产| 顶级嫩模精品视频在线看| 免费在线观看av网址| 精品国产乱码久久久久久1区2区| 黄色大片在线| 久久国产精品 国产精品| 午夜在线一区| 国产人妻大战黑人20p| 欧美影院精品一区| 日韩专区在线| 亚洲一区国产精品| 一区在线播放| 日韩av在线看免费观看| 日本高清成人免费播放| 在线免费观看黄色av| 亚洲最大的成人网| 狠狠色丁香久久综合频道| 图片区偷拍区小说区| 欧美日韩国产在线看| sese在线视频| 99re视频| 噜噜噜在线观看免费视频日韩| 一区二区三区在线观看免费视频| 4438x成人网最大色成网站| 大桥未久在线播放| 欧美日韩无遮挡| 国产资源在线一区| 日韩av免费网址| 国产亚洲一级高清| 高清一区二区三区av| 亚洲 自拍 另类小说综合图区| 久久久五月婷婷| 国产免费一区二区三区免费视频| 久久久免费观看视频| 久久超碰99| 中文字幕无码毛片免费看| 欧美日韩国产综合新一区 | 亚洲欧美激情国产综合久久久| 国外成人在线视频| 欧美最新另类人妖| 国产ts在线观看| 欧美主播一区二区三区| 黄页网站在线观看免费| 亚洲精品tv久久久久久久久| 高清shemale亚洲人妖| 免费在线不卡视频| www.欧美精品|