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

圖文詳解Java對象內存布局

開發 后端
本文將基于代碼進行實例測試,詳細探討對象在內存中的組成結構。

[[395489]]

作為一名Java程序員,我們在日常工作中使用這款面向對象的編程語言時,做的最頻繁的操作大概就是去創建一個個的對象了。對象的創建方式雖然有很多,可以通過new、反射、clone、反序列化等不同方式來創建,但最終使用時對象都要被放到內存中,那么你知道在內存中的java對象是由哪些部分組成、又是怎么存儲的嗎?

本文將基于代碼進行實例測試,詳細探討對象在內存中的組成結構。全文目錄結構如下:

  1. 對象內存結構概述
  2. JOL 工具簡介
  3. 對象頭
  4. 實例數據
  5. 對齊填充字節
  6. 總結

文中代碼基于 JDK 1.8.0_261,64-Bit HotSpot 運行

1、對象內存結構概述

在介紹對象在內存中的組成結構前,我們先簡要回顧一個對象的創建過程:

1、jvm將對象所在的class文件加載到方法區中

2、jvm讀取main方法入口,將main方法入棧,執行創建對象代碼

3、在main方法的棧內存中分配對象的引用,在堆中分配內存放入創建的對象,并將棧中的引用指向堆中的對象

所以當對象在實例化完成之后,是被存放在堆內存中的,這里的對象由3部分組成,如下圖所示:

對各個組成部分的功能簡要進行說明:

  • 對象頭:對象頭存儲的是對象在運行時狀態的相關信息、指向該對象所屬類的元數據的指針,如果對象是數組對象那么還會額外存儲對象的數組長度
  • 實例數據:實例數據存儲的是對象的真正有效數據,也就是各個屬性字段的值,如果在擁有父類的情況下,還會包含父類的字段。字段的存儲順序會受到數據類型長度、以及虛擬機的分配策略的影響
  • 對齊填充字節:在java對象中,需要對齊填充字節的原因是,64位的jvm中對象的大小被要求向8字節對齊,因此當對象的長度不足8字節的整數倍時,需要在對象中進行填充操作。注意圖中對齊填充部分使用了虛線,這是因為填充字節并不是固定存在的部分,這點在后面計算對象大小時具體進行說明

2、JOL 工具簡介

在具體開始研究對象的內存結構之前,先介紹一下我們要用到的工具,openjdk官網提供了查看對象內存布局的工具jol (java object layout),可在maven中引入坐標:

  1. <dependency> 
  2.     <groupId>org.openjdk.jol</groupId> 
  3.     <artifactId>jol-core</artifactId> 
  4.     <version>0.14</version> 
  5. </dependency> 

在代碼中使用jol提供的方法查看jvm信息:

  1. System.out.println(VM.current().details()); 

 

通過打印出來的信息,可以看到我們使用的是64位 jvm,并開啟了指針壓縮,對象默認使用8字節對齊方式。通過jol查看對象內存布局的方法,將在后面的例子中具體展示,下面開始對象內存布局的正式學習。

3、對象頭

首先看一下對象頭(Object header)的組成部分,根據普通對象和數組對象的不同,結構將會有所不同。只有當對象是數組對象才會有數組長度部分,普通對象沒有該部分,如下圖所示:

在對象頭中mark word 占8字節,默認開啟指針壓縮的情況下klass pointer 占4字節,數組對象的數組長度占4字節。在了解了對象頭的基礎結構后,現在以一個不包含任何屬性的空對象為例,查看一下它的內存布局,創建User類:

  1. public class User { 

使用jol查看對象頭的內存布局:

  1. public static void main(String[] args) { 
  2.     User user=new User(); 
  3.     //查看對象的內存布局 
  4.     System.out.println(ClassLayout.parseInstance(user).toPrintable()); 

執行代碼,查看打印信息:

  • OFFSET:偏移地址,單位為字節
  • SIZE:占用內存大小,單位為字節
  • TYPE:Class中定義的類型
  • DESCRIPTION:類型描述,Obejct header 表示對象頭,alignment表示對齊填充
  • VALUE:對應內存中存儲的值

當前對象共占用16字節,因為8字節標記字加4字節的類型指針,不滿足向8字節對齊,因此需要填充4個字節:

  1. 8B (mark word) + 4B (klass pointer) + 0B (instance data) + 4B (padding) 

這樣我們就通過直觀的方式,了解了一個不包含屬性的最簡單的空對象,在內存中的基本組成是怎樣的。在此基礎上,我們來深入學習對象頭中各個組成部分。

3.1 Mark Word 標記字

在對象頭中,mark word 一共有64個bit,用于存儲對象自身的運行時數據,標記對象處于以下5種狀態中的某一種:

3.1.1 基于mark word的鎖升級

在jdk6 之前,通過synchronized關鍵字加鎖時使用無差別的的重量級鎖,重量級鎖會造成線程的串行執行,并且使cpu在用戶態和核心態之間頻繁切換。隨著對synchronized的不斷優化,提出了鎖升級的概念,并引入了偏向鎖、輕量級鎖、重量級鎖。在mark word中,鎖(lock)標志位占用2個bit,結合1個bit偏向鎖(biased_lock)標志位,這樣通過倒數的3位,就能用來標識當前對象持有的鎖的狀態,并判斷出其余位存儲的是什么信息。

基于mark word的鎖升級的流程如下:

1、鎖對象剛創建時,沒有任何線程競爭,對象處于無鎖狀態。在上面打印的空對象的內存布局中,根據大小端,得到最后8位是00000001,表示處于無鎖態,并且處于不可偏向狀態。這是因為在jdk中偏向鎖存在延遲4秒啟動,也就是說在jvm啟動后4秒后創建的對象才會開啟偏向鎖,我們通過jvm參數取消這個延遲時間:

  1. -XX:BiasedLockingStartupDelay=0 

 

這時最后3位為101,表示當前對象的鎖沒有被持有,并且處于可被偏向狀態。

2、在沒有線程競爭的條件下,第一個獲取鎖的線程通過CAS將自己的threadId寫入到該對象的mark word中,若后續該線程再次獲取鎖,需要比較當前線程threadId和對象mark word中的threadId是否一致,如果一致那么可以直接獲取,并且鎖對象始終保持對該線程的偏向,也就是說偏向鎖不會主動釋放。

使用代碼進行測試同一個線程重復獲取鎖的過程:

  1. public static void main(String[] args) { 
  2.     User user=new User(); 
  3.     synchronized (user){ 
  4.         System.out.println(ClassLayout.parseInstance(user).toPrintable()); 
  5.     } 
  6.     System.out.println(ClassLayout.parseInstance(user).toPrintable()); 
  7.     synchronized (user){ 
  8.         System.out.println(ClassLayout.parseInstance(user).toPrintable()); 
  9.     } 

執行結果:

可以看到一個線程對一個對象加鎖、解鎖、重新獲取對象的鎖時,mark word都沒有發生變化,偏向鎖中的當前線程指針始終指向同一個線程。

3、當兩個或以上線程交替獲取鎖,但并沒有在對象上并發的獲取鎖時,偏向鎖升級為輕量級鎖。在此階段,線程采取CAS的自旋方式嘗試獲取鎖,避免阻塞線程造成的cpu在用戶態和內核態間轉換的消耗。測試代碼如下:

  1. public static void main(String[] args) throws InterruptedException { 
  2.     User user=new User(); 
  3.     synchronized (user){ 
  4.         System.out.println("--MAIN--:"+ClassLayout.parseInstance(user).toPrintable()); 
  5.     } 
  6.  
  7.     Thread thread = new Thread(() -> { 
  8.         synchronized (user) { 
  9.             System.out.println("--THREAD--:"+ClassLayout.parseInstance(user).toPrintable()); 
  10.         } 
  11.     }); 
  12.     thread.start(); 
  13.     thread.join(); 
  14.     System.out.println("--END--:"+ClassLayout.parseInstance(user).toPrintable()); 

先直接看一下結果:

整個加鎖狀態的變化流程如下:

  • 主線程首先對user對象加鎖,首次加鎖為101偏向鎖
  • 子線程等待主線程釋放鎖后,對user對象加鎖,這時將偏向鎖升級為00輕量級鎖
  • 輕量級鎖解鎖后,user對象無線程競爭,恢復為001無鎖態,并且處于不可偏向狀態。如果之后有線程再嘗試獲取user對象的鎖,會直接加輕量級鎖,而不是偏向鎖

4、當兩個或以上線程并發的在同一個對象上進行同步時,為了避免無用自旋消耗cpu,輕量級鎖會升級成重量級鎖。這時mark word中的指針指向的是monitor對象(也被稱為管程或監視器鎖)的起始地址。測試代碼如下:

  1. public static void main(String[] args) { 
  2.     User user = new User(); 
  3.     new Thread(() -> { 
  4.         synchronized (user) { 
  5.             System.out.println("--THREAD1--:" + ClassLayout.parseInstance(user).toPrintable()); 
  6.             try { 
  7.                 TimeUnit.SECONDS.sleep(2); 
  8.             } catch (InterruptedException e) { 
  9.                 e.printStackTrace(); 
  10.             } 
  11.         } 
  12.     }).start(); 
  13.     new Thread(() -> { 
  14.         synchronized (user) { 
  15.             System.out.println("--THREAD2--:" + ClassLayout.parseInstance(user).toPrintable()); 
  16.             try { 
  17.                 TimeUnit.SECONDS.sleep(2); 
  18.             } catch (InterruptedException e) { 
  19.                 e.printStackTrace(); 
  20.             } 
  21.         } 
  22.     }).start(); 

查看結果:

可以看到,在兩個線程同時競爭user對象的鎖時,會升級為10重量級鎖。

3.1.2 其他信息

對mark word 中其他重要信息進行說明:

hashcode:無鎖態下的hashcode采用了延遲加載技術,在第一次調用hashCode()方法時才會計算寫入。對這一過程進行驗證:

  1. public static void main(String[] args) { 
  2.     User user=new User(); 
  3.     //打印內存布局 
  4.     System.out.println(ClassLayout.parseInstance(user).toPrintable()); 
  5.     //計算hashCode 
  6.     System.out.println(user.hashCode()); 
  7.     //再次打印內存布局 
  8.     System.out.println(ClassLayout.parseInstance(user).toPrintable()); 

 

可以看到,在沒有調用hashCode()方法前,31位的哈希值不存在,全部填充為0。在調用方法后,根據大小端,被填充的數據為:

  1. 1011001001101100011010010101101 

將2進制轉換為10進制,對應哈希值1496724653。需要注意,只有在調用沒有被重寫的Object.hashCode()方法或System.identityHashCode(Object)方法才會寫入mark word,執行用戶自定義的hashCode()方法不會被寫入。

大家可能會注意到,當對象被加鎖后,mark word中就沒有足夠空間來保存hashCode了,這時hashcode會被移動到重量級鎖的Object Monitor中。

  • epoch:偏向鎖的時間戳
  • 分代年齡(age):在jvm的垃圾回收過程中,每當對象經過一次Young GC,年齡都會加1,這里4位來表示分代年齡最大值為15,這也就是為什么對象的年齡超過15后會被移到老年代的原因。在啟動時可以通過添加參數來改變年齡閾值:
  1. -XX:MaxTenuringThreshold 

當設置的閾值超過15時,啟動時會報錯:

3.2 Klass Pointer 類型指針

Klass Pointer是一個指向方法區中Class信息的指針,虛擬機通過這個指針確定該對象屬于哪個類的實例。在64位的JVM中,支持指針壓縮功能,根據是否開啟指針壓縮,Klass Pointer占用的大小將會不同:

  • 未開啟指針壓縮時,類型指針占用8B (64bit)
  • 開啟指針壓縮情況下,類型指針占用4B (32bit)

在jdk6之后的版本中,指針壓縮是被默認開啟的,可通過啟動參數開啟或關閉該功能:

  1. #開啟指針壓縮: 
  2. -XX:+UseCompressedOops 
  3. #關閉指針壓縮: 
  4. -XX:-UseCompressedOops 

還是以剛才的User類為例,關閉指針壓縮后再次查看對象的內存布局:

對象大小雖然還是16字節,但是組成發生了改變,8字節標記字加8字節類型指針,已經能滿足對齊條件,因此不需要填充。

  1. 8B (mark word) + 8B (klass pointer) + 0B (instance data) + 0B (padding) 

3.2.1 指針壓縮原理

在了解了指針壓縮的作用后,我們來看一下指針壓縮是如何實現的。首先在不開啟指針壓縮的情況下,一個對象的內存地址使用64位表示,這時能描述的內存地址范圍是:

  1. 0 ~ 2^64-1 

在開啟指針壓縮后,使用4個字節也就是32位,可以表示2^32 個內存地址,如果這個地址是真實地址的話,由于CPU尋址的最小單位是Byte,那么就是4GB內存。這對于我們來說是遠遠不夠的,但是之前我們說過,java中對象默認使用了8字節對齊,也就是說1個對象占用的空間必須是8字節的整數倍,這樣就創造了一個條件,使jvm在定位一個對象時不需要使用真正的內存地址,而是定位到由java進行了8字節映射后的地址(可以說是一個映射地址的編號)。

映射過程也非常簡單,由于使用了8字節對齊后每個對象的地址偏移量后3位必定為0,所以在存儲的時候可以將后3位0抹除(轉化為bit是抹除了最后24位),在此基礎上再去掉最高位,就完成了指針從8字節到4字節的壓縮。而在實際使用時,在壓縮后的指針后加3位0,就能夠實現向真實地址的映射。

完成壓縮后,現在指針的32位中的每一個bit,都可以代表8個字節,這樣就相當于使原有的內存地址得到了8倍的擴容。所以在8字節對齊的情況下,32位最大能表示2^32*8=32GB內存,內存地址范圍是:

  1. 0 ~ (2^32-1)*8 

由于能夠表示的最大內存是32GB,所以如果配置的最大的堆內存超過這個數值時,那么指針壓縮將會失效。配置jvm啟動參數:

  1. -Xmx32g 

查看對象內存布局:

 

此時,指針壓縮失效,指針長度恢復到8字節。那么如果業務場景內存超過32GB怎么辦呢,可以通過修改默認對齊長度進行再次擴展,我們將對齊長度修改為16字節:

  1. -XX:ObjectAlignmentInBytes=16 -Xmx32g 

 

可以看到指針壓縮后占4字節,同時對象向16字節進行了填充對齊,按照上面的計算,這時配置最大堆內存為64GB時指針壓縮才會失效。

對指針壓縮做一下簡單總結:

  • 通過指針壓縮,利用對齊填充的特性,通過映射方式達到了內存地址擴展的效果
  • 指針壓縮能夠節省內存空間,同時提高了程序的尋址效率
  • 堆內存設置時最好不要超過32GB,這時指針壓縮將會失效,造成空間的浪費
  • 此外,指針壓縮不僅可以作用于對象頭的類型指針,還可以作用于引用類型的字段指針,以及引用類型數組指針

3.3 數組長度

如果當對象是一個數組對象時,那么在對象頭中有一個保存數組長度的空間,占用4字節(32bit)空間。通過下面代碼進行測試:

  1. public static void main(String[] args) { 
  2.     User[] user=new User[2]; 
  3.     //查看對象的內存布局 
  4.     System.out.println(ClassLayout.parseInstance(user).toPrintable()); 

運行代碼,結果如下:

內存結構從上到下分別為:

  • 8字節mark word
  • 4字節klass pointer
  • 4字節數組長度,值為2,表示數組中有兩個元素
  • 開啟指針壓縮后每個引用類型占4字節,數組中兩個元素共占8字節

需要注意的是,在未開啟指針壓縮的情況下,在數組長度后會有一段對齊填充字節:

通過計算:

  1. 8B (mark word) + 8B (klass pointer) + 4B (array length) + 16B (instance data)=36B 

需要向8字節進行對齊,這里選擇將對齊的4字節添加在了數組長度和實例數據之間。

4、實例數據

實例數據(Instance Data)保存的是對象真正存儲的有效信息,保存了代碼中定義的各種數據類型的字段內容,并且如果有繼承關系存在,子類還會包含從父類繼承過來的字段。

  • 基本數據類型:

  • 引用數據類型:

開啟指針壓縮情況下占8字節,開啟指針壓縮后占4字節。

4.1 字段重排序

給User類添加基本數據類型的屬性字段:

  1. public class User { 
  2.     int id,age,weight; 
  3.     byte sex; 
  4.     long phone; 
  5.     char local

查看內存布局:

可以看到,在內存中,屬性的排列順序與在類中定義的順序不同,這是因為jvm會采用字段重排序技術,對原始類型進行重新排序,以達到內存對齊的目的。具體規則遵循如下:

  • 按照數據類型的長度大小,從大到小排列
  • 具有相同長度的字段,會被分配在相鄰位置
  • 如果一個字段的長度是L個字節,那么這個字段的偏移量(OFFSET)需要對齊至nL(n為整數)

上面的前兩條規則相對容易理解,這里通過舉例對第3條進行解釋:

因為long類型占8字節,所以它的偏移量必定是8n,再加上前面對象頭占12字節,所以long類型變量的最小偏移量是16。通過打印對象內存布局可以發現,當對象頭不是8字節的整數倍時(只存在8n+4字節情況),會按從大到小的順序,使用4、2、1字節長度的屬性進行補位。為了和對齊填充進行區分,可以稱其為前置補位,如果在補位后仍然不滿足8字節整數倍,會進行對齊填充。在存在前置補位的情況下,字段的排序會打破上面的第一條規則。

因此在上面的內存布局中,先使用4字節的int進行前置補位,再按第一條規則從大到小順序進行排列。如果我們刪除3個int類型的字段,再查看內存布局:

char和byte類型的變量被提到前面進行前置補位,并在long類型前進行了1字節的對齊填充。

4.2 擁有父類情況

當一個類擁有父類時,整體遵循在父類中定義的變量出現在子類中定義的變量之前的原則

  1. public class A { 
  2.     int i1,i2; 
  3.     long l1,l2; 
  4.     char c1,c2; 
  5. public class B extends A{ 
  6.     boolean b1; 
  7.     double d1,d2; 

查看內存結構:

如果父類需要后置補位的情況,可能會將子類中類型長度較短的變量提前,但是整體還是遵循子類在父類之后的原則

  1. public class A { 
  2.     int i1,i2; 
  3.     long l1; 
  4. public class B extends A { 
  5.     int i1,i2; 
  6.     long l1; 

查看內存結構:

可以看到,子類中較短長度的變量被提前到父類后進行了后置補位。

父類的前置對齊填充會被子類繼承

  1. public class A { 
  2.     long l; 
  3. public class B extends A{ 
  4.     long l2; 
  5.     int i1; 

查看內存結構:

當B類沒有繼承A類時,正好滿足8字節對齊,不需要進行對齊填充。當B類繼承A類后,會繼承A類的前置補位填充,因此在B類的末尾也需要對齊填充。

4.3 引用數據類型

在上面的例子中,僅探討了基本數據類型的排序情況,那么如果存在引用數據類型時,排序情況是怎樣的呢?在User類中添加引用類型:

  1. public class User { 
  2.      int id; 
  3.      String firstName; 
  4.      String lastName; 
  5.      int age; 

查看內存布局:

可以看到默認情況下,基本數據類型的變量排在引用數據類型前。這個順序可以在jvm啟動參數中進行修改:

  1. -XX:FieldsAllocationStyle=0 

重新運行,可以看到引用數據類型的排列順序被放在了前面:

對FieldsAllocationStyle的不同取值簡要說明:

  • 0:先放入普通對象的引用指針,再放入基本數據類型變量
  • 1:默認情況,表示先放入基本數據類型變量,再放入普通對象的引用指針

4.4 靜態變量

在上面的基礎上,在類中加入靜態變量:

  1. public class User { 
  2.      int id; 
  3.      static byte local

查看內存布局:

通過結果可以看到,靜態變量并不在對象的內存布局中,它的大小是不計算在對象中的,因為靜態變量屬于類而不是屬于某一個對象的。

5、對齊填充字節

在Hotspot的自動內存管理系統中,要求對象的起始地址必須是8字節的整數倍,也就是說對象的大小必須滿足8字節的整數倍。因此如果實例數據沒有對齊,那么需要進行對齊補全空缺,補全的bit位僅起占位符作用,不具有特殊含義。

在前面的例子中,我們已經對對齊填充有了充分的認識,下面再做一些補充:

  • 在開啟指針壓縮的情況下,如果類中有long/double類型的變量時,會在對象頭和實例數據間形成間隙(gap),為了節省空間,會默認把較短長度的變量放在前邊,這一功能可以通過jvm參數進行開啟或關閉:
  1. # 開啟 
  2. -XX:+CompactFields 
  3. # 關閉 
  4. -XX:-CompactFields 

測試關閉情況,可以看到較短長度的變量沒有前移填充:

在前面指針壓縮中,我們提到了可以改變對齊寬度,這也是通過修改下面的jvm參數配置實現的:

  1. -XX:ObjectAlignmentInBytes 

默認情況下對齊寬度為8,這個值可以修改為2~256以內2的整數冪,一般情況下都以8字節對齊或16字節對齊。測試修改為16字節對齊:


上面的例子中,在調整為16字節對齊的情況下,最后一行的屬性字段只占了6字節,因此會添加10字節進行對齊填充。當然普通情況下不建議修改對齊長度參數,如果對齊寬度過長,可能會導致內存空間的浪費。

6、總結

本文通過使用jol 對java對象的結構進行調試,學習了對象內存布局的基本知識。通過學習,能夠幫助我們:

  • 掌握對象內存布局,基于此基礎進行jvm參數調優
  • 了解對象頭在synchronize 的鎖升級過程中的作用
  • 熟悉 jvm 中對象的尋址過程
  • 通過計算對象大小,可以在評估業務量的基礎上在項目上線前預估需要使用多少內存,防止服務器頻繁gc

 

責任編輯:姜華 來源: 碼農參上
相關推薦

2020-09-25 07:55:51

內存Java對象

2011-07-04 16:57:36

QT 布局 界面

2022-07-06 08:05:52

Java對象JVM

2019-09-02 14:53:53

JVM內存布局GC

2009-06-24 16:50:11

Java內存模型

2010-06-23 10:03:01

2024-07-25 14:18:29

2013-03-28 09:55:37

Java對象

2012-02-09 10:18:55

Java

2009-08-07 11:46:57

JAVA虛擬機安裝設置

2024-07-26 10:35:00

2024-09-04 09:43:36

2009-12-10 19:02:30

2011-11-21 15:12:54

Java斷點Eclipse

2025-08-27 06:25:00

MSTP網絡端口

2015-10-26 15:48:51

安裝Ubuntu 15.1Linux

2018-02-07 09:25:50

Linux命令touch

2025-10-11 01:24:00

gcc -gELFDWARF

2020-03-23 09:17:32

內存操作系統Windows

2024-04-10 07:40:45

Java虛擬機內存
點贊
收藏

51CTO技術棧公眾號

亲爱的老师9免费观看全集电视剧| www.九色在线| 97成人超碰| 欧美成人精品一区二区三区在线看| 中文字幕永久在线不卡| 午夜精品久久久99热福利| 2025韩国理伦片在线观看| 欧美成人国产精品高潮| 欧美成人a交片免费看| 国产综合久久久久久鬼色| 亚洲精品乱码久久久久久金桔影视| 日韩一本精品| 中文字幕激情小说| 91精品久久久久久综合五月天| 国产日产欧美一区| 91精品国产精品| 黄色三级视频在线播放| 欧美日韩在线精品一区二区三区激情综 | 亚洲天堂网2018| 你懂得网站在线| 国产毛片一区二区| 欧美美女18p| 激情久久综合网| 中文字幕人成乱码在线观看| 成人高清在线视频| 欧美极品欧美精品欧美视频| 波多野吉衣在线视频| 黄色网在线播放| 久草中文综合在线| 久久精品男人天堂| 亚洲一区二区偷拍| 日韩在线影院| 婷婷成人激情在线网| 国产伦精品一区二区三区视频免费| 中文字幕电影av| 亚洲日本视频在线| 在线观看日韩电影| 亚洲在线色站| 国产喷水吹潮视频www| 午夜精彩国产免费不卡不顿大片| 欧美一区二区日韩一区二区| 国产精品av免费观看| 亚洲精品.www| 米奇777在线欧美播放| 一区二区三区精品99久久 | 久久国产精品毛片| 久久久久久久色| 欧美国产精品一二三| 婷婷综合久久| 精品欧美一区二区在线观看| 国产免费黄色一级片| 天天摸夜夜添狠狠添婷婷| 亚洲综合国产| 久久精品电影网站| 99久久久无码国产精品不卡| 精品一区二区三区中文字幕在线 | 玖玖精品在线| 最新欧美精品一区二区三区| 99视频免费观看| 日本一区二区三区免费视频| 欧美日韩xxxx| 欧美人动与zoxxxx乱| 国产1区2区3区中文字幕| jizzjizz亚洲| 久久在线观看免费| 91日韩在线播放| 国产69精品久久久久久久久久| 欧美限制电影| 精品久久久久久久人人人人传媒| 香蕉在线观看视频| 久久99国产精品久久99大师| 欧美在线一二三四区| 91热这里只有精品| xxx性欧美| 中文字幕一区二区三| 亚洲一区二区三区加勒比| 美女国产在线| 久久久欧美精品sm网站| 91视频网页| 五月婷婷丁香在线| 99热在线精品观看| 久久精品视频va| 美女的奶胸大爽爽大片| 精品1区2区3区4区| 色阁综合伊人av| 黄色性生活一级片| **爰片久久毛片| 亚洲高清在线观看| 黄色一级片免费播放| 久久视频免费| 亚洲欧美另类人妖| fc2成人免费视频| 伊人久久精品| 欧美日韩卡一卡二| 日批视频在线看| 99re久久| 日韩欧美一级在线播放| 男人的天堂最新网址| 日韩中文字幕在线一区| 欧美日韩一区三区四区| 成人小视频在线看| 瑟瑟视频在线看| 激情亚洲一区二区三区四区| 男人插女人下面免费视频| 免费精品一区| 国产亚洲综合久久| 全黄一级裸体片| 亚洲黄页在线观看| 亚洲精品理论电影| 亚洲综合久久av一区二区三区| 狠狠色狠狠色综合婷婷tag| 日韩毛片中文字幕| 屁屁影院国产第一页| 岛国成人av| 亚洲丁香久久久| 妖精视频在线观看免费| 首页国产精品| 91精品国产高清久久久久久久久 | 欧美成人官网二区| 中文字幕黄色网址| 奇米狠狠一区二区三区| 麻豆乱码国产一区二区三区| 欧美人禽zoz0强交| 欧美黄色一区二区| 日本高清视频一区| 日本人妻丰满熟妇久久久久久| 成人免费视频一区二区| 国产精品麻豆免费版| 麻豆影院在线观看| 在线观看欧美日本| 精品人妻无码一区二区三区换脸| 国产精品一在线观看| 国内精品久久久久久久| 国产黄色免费观看| 成人精品国产福利| 久久精品在线免费视频| av免费不卡| 色呦呦一区二区三区| 九九热免费精品视频| 神马香蕉久久| 最近2019年中文视频免费在线观看| 日韩精品一区二区三区国语自制| 国产精品亚洲一区二区三区妖精| 亚洲三级一区| 123成人网| 欧美一级搡bbbb搡bbbb| av资源在线免费观看| 日韩av午夜在线观看| 91精品在线影院| 日本激情在线观看| 偷拍一区二区三区| 日韩精品人妻中文字幕有码| 精品一区av| 久久视频在线免费观看| 在线视频欧美亚洲| 9l国产精品久久久久麻豆| 日本午夜精品一区二区| 成人福利在线观看视频| 欧美丰满一区二区免费视频| www.17c.com喷水少妇| 韩国亚洲精品| 国产精品入口免费视频一| 亚洲国产视频一区二区三区| 一区二区三区不卡视频 | 久久久久久久久久97| 免费看欧美女人艹b| 国产成人女人毛片视频在线| 黑人与亚洲人色ⅹvideos | 亚洲视频小说| 成人日韩视频| 精品亚洲一区二区三区在线播放 | 奇米色一区二区| 亚洲一区在线免费| 亚洲三区欧美一区国产二区| 久久久久久久一区二区| 亚洲 小说区 图片区 都市| 国产精品欧美综合在线| 亚洲熟妇国产熟妇肥婆| 国产成年精品| 欧美激情在线观看视频| 四虎成人免费在线| 一区二区三区久久久| 日本一区二区免费视频| 国产精品久久观看| 99久久99久久| av资源亚洲| 亚洲精品99久久久久| 国产不卡在线观看视频| 九一九一国产精品| 国产69精品久久久久999小说| 综合综合综合综合综合网| 91精品久久久久久久久久另类| 欧美在线 | 亚洲| 日韩欧美在线免费观看| 91视频在线免费| 日韩精品成人一区二区三区 | 亚洲黄色在线观看视频| 色视频欧美一区二区三区| 日本国产在线视频| 日韩黄色在线观看| 国产片侵犯亲女视频播放| 国产乱码精品一区二区三区亚洲人| 欧美激情一区二区三区在线视频观看 | 少妇在线看www| 日韩一区二区欧美| 波多野结衣黄色网址| 久久婷婷一区二区三区| 在线免费黄色网| 另类国产ts人妖高潮视频| 麻豆视频传媒入口| 欧洲福利电影| 精品伊人久久大线蕉色首页| 影音先锋在线视频| 日韩精品中文字幕在线一区| 区一区二在线观看| 国产日韩av一区二区| 99热超碰在线| 国产一区二区久久| 亚洲综合在线网站| 欧美日韩伦理| 九九九九久久久久| 日韩不卡免费高清视频| 欧美激情一级欧美精品| а√中文在线8| 色噜噜国产精品视频一区二区| 外国精品视频在线观看| 精品人在线二区三区| 国产视频一二三四区| 欧美色精品在线视频| www.久久久久久久| 国产情人综合久久777777| 久久婷婷综合色| 亚洲精品网址| 国产九色精品| 日韩精品亚洲专区在线观看| 国产日产欧美精品| 三级网站视频在在线播放| 亚洲成人网在线| 丰满人妻一区二区三区免费| 欧美日韩免费在线观看| 又嫩又硬又黄又爽的视频| 91麻豆福利精品推荐| 亚洲小视频网站| 日本va欧美va瓶| 毛片毛片毛片毛片毛片毛片毛片毛片毛片 | 亚洲男人天天操| 日本1级在线| 欧美日韩国产首页在线观看| 国产99久久久久久免费看| 色欧美片视频在线观看 | a级片免费在线观看| 久久99精品久久久久久青青91 | 天天干,夜夜操| 亚洲国产精品久久久久秋霞蜜臀 | 中文一区二区三区四区| 91在线在线观看| 亚洲国产视频二区| 国产99视频精品免费视频36| 大奶在线精品| 农村寡妇一区二区三区| 亚洲精品三区| 91亚洲精品久久久久久久久久久久| 高清一区二区中文字幕| 成人动漫视频在线观看完整版| 999精品视频在这里| 国产精品美乳一区二区免费| 欧美精品资源| 成人激情免费在线| 51亚洲精品| 久久99精品国产一区二区三区| 久久超碰99| 在线观看亚洲视频啊啊啊啊| 麻豆一区一区三区四区| 欧美久久综合性欧美| 亚洲综合影院| 国产一区国产精品| 亚洲精品一二三**| 国产精品推荐精品| 久久av资源| 青青草原国产免费| 凹凸成人精品亚洲精品密奴| 偷拍盗摄高潮叫床对白清晰| 狠狠干成人综合网| 黄色高清无遮挡| 国产情侣一区| 久久99久久99精品| 欧美日韩伊人| 亚洲高清在线观看一区| 婷婷综合一区| 欧美aaa在线观看| 日韩五码在线| 性生活免费在线观看| 成人美女在线观看| 欧美成人久久久免费播放| 亚洲国产视频一区二区| a级在线免费观看| 亚洲另类春色国产| 最新一区二区三区| 欧美日韩一区二区在线| 国产一区二区三区在线观看| 在线观看视频一区| 蜜臀久久99精品久久久| 这里只有精品视频在线| 高清毛片在线看| 国产一区二区三区视频在线观看 | 亚洲人成网77777色在线播放| 亚洲欧洲一区二区福利| 在线亚洲自拍| 乳色吐息在线观看| 国产精品久久国产精麻豆99网站| 日本中文字幕网| 欧美一二三四区在线| 国产精品女同一区二区| 91精品欧美一区二区三区综合在| 91精品国产乱码久久| 日韩久久精品成人| av老司机在线观看| 亚洲综合中文字幕在线| 91久久精品无嫩草影院| 亚洲欧美日韩国产yyy| 中日韩男男gay无套| 免费观看污网站| 亚洲欧美视频在线观看| 国产第100页| 欧美视频中文字幕在线| av免费在线不卡| 亚洲第一视频网站| 91国内在线| 91老司机在线| 国产精品精品| 日本高清久久久| 中文字幕免费不卡在线| 欧美激情精品久久久久久免费 | 116极品美女午夜一级| 免费在线日韩av| 国产情侣久久久久aⅴ免费| 一区二区三区在线视频免费| 三级黄色在线视频| 在线观看国产日韩| 日色在线视频| 欧美有码在线视频| 日日夜夜亚洲| 国产亚洲欧美一区二区三区| 欧美日本一区二区高清播放视频| 天堂av2020| av电影在线观看不卡| 久久精品国产亚洲av高清色欲| 欧美一二三四区在线| 日本一本在线免费福利| 成人资源视频网站免费| 好看的日韩av电影| 成熟妇人a片免费看网站| 婷婷中文字幕综合| 色播色播色播色播色播在线| 茄子视频成人在线| 色综合久久一区二区三区| 国产美女在线一区| 99精品久久久久久| 欧美日韩午夜视频| 欧美成人综合网站| 精精国产xxxx视频在线中文版| 国产精品jizz在线观看麻豆| 电影中文字幕一区二区| 777久久精品一区二区三区无码| 国产精品一二三区在线| 亚州国产精品视频| 亚洲美女黄色片| 欧美v亚洲v综合v国产v仙踪林| 中文字幕欧美日韩一区二区三区| 国产一区二区看久久| 日本少妇裸体做爰| 一区二区三区美女xx视频| 国产精品美女久久久久| 久无码久无码av无码| 久久婷婷成人综合色| 亚洲中文字幕一区二区| 欧美日韩成人免费| 天堂99x99es久久精品免费| www亚洲成人| 亚洲午夜在线观看视频在线| 欧美日韩影视| 97人人做人人人难人人做| 亚洲在线一区| 国产wwwwxxxx| 亚洲成人黄色在线观看| 日韩一级二级| 男人添女人荫蒂免费视频| 国产网红主播福利一区二区| 国产女无套免费视频| 欧美在线视频观看免费网站| 色综合久久网| 91精品人妻一区二区三区蜜桃欧美| 在线播放91灌醉迷j高跟美女| 9999精品成人免费毛片在线看 | 午夜久久福利| 亚洲欧洲久久久| 欧美精品一区二区三区一线天视频| 国产秀色在线www免费观看| 国产在线一区二区三区播放| 久久国产乱子精品免费女|