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

來聊聊 JVM 中安全點(diǎn)的概念

開發(fā)
本文從JVM工作原理引出安全點(diǎn)的作用、工作方式、常見配置和一些性能表現(xiàn)上的風(fēng)險(xiǎn)點(diǎn),從而給出一些比較經(jīng)典的實(shí)踐案例,希望對(duì)你有幫助。

近期在分享關(guān)于synchronized關(guān)鍵字的文章的時(shí)候提到了一個(gè)關(guān)于安全點(diǎn)的概念,有讀者反饋這塊知識(shí)點(diǎn)講的有些潦草,遂以此文簡(jiǎn)單介紹一下JVM中關(guān)于安全點(diǎn)的概念。

一、詳解safepoint基本概念

1. 什么是安全點(diǎn)?為什么需要安全點(diǎn)

在正式講解安全點(diǎn)之前,我們不妨復(fù)習(xí)一下JVM中垃圾回收的基本過程,我們以CMS垃圾回收器為例,其垃圾回收過程在完成GC Roots查找與收集之后就會(huì)按照如下步驟執(zhí)行:

  • 初始標(biāo)記
  • 并發(fā)回收
  • 最終標(biāo)記(重新標(biāo)記)
  • 并發(fā)清除

要知道固定可作為GC Roots的節(jié)點(diǎn)主要是:

  • 全局引用:例如常量或者靜態(tài)變量。
  • 執(zhí)行上下文即棧幀中的變量表。

對(duì)于現(xiàn)代java應(yīng)用而言,光是方法區(qū)就可能有數(shù)百上千兆,所以對(duì)于這些起源的引用也并非一件容易的事情。這也就意味著JVM在進(jìn)行垃圾回收時(shí)并不能通過逐個(gè)掃描檢查來實(shí)現(xiàn)。 就目前主流的JVM來說,針對(duì)根節(jié)點(diǎn)枚舉基本都是采用空間換時(shí)間的策略,也就是使用一組OopMap,全稱為"Object Pointer Map"(對(duì)象指針映射),本質(zhì)上就是一個(gè)位圖索引,它會(huì)通過以下兩個(gè)時(shí)機(jī)完成對(duì)象信息的緩存:

  • 類加載完成后,hotSpot就會(huì)基于類的偏移量信息計(jì)算出來并緩存。
  • JIT階段也會(huì)在特定的時(shí)機(jī)(這一點(diǎn)后續(xù)會(huì)詳細(xì)說明)計(jì)算出棧或寄存器中的那些位置是引用,并將其緩存。

如此一來,下次進(jìn)行根枚舉時(shí)就可以直接基于OopMap高效完成:

但是java進(jìn)程的運(yùn)行的瞬息萬變的,可能此刻的對(duì)象在下一刻就不可用,下一刻又有新的對(duì)象誕生,這種引用關(guān)系的實(shí)時(shí)變化亦或者說導(dǎo)致OopMap內(nèi)容變化的指令是非常多的,若針對(duì)每一個(gè)指令都設(shè)置對(duì)應(yīng)的oopMap,那么內(nèi)存的開銷是非常高昂的。

所以就有了安全點(diǎn)(safepoint)的概念,這也就是我們上文所提及的特定的位置,基于這個(gè)設(shè)定,用戶的程序僅僅會(huì)在特定的情況下生成oopMap,同理在垃圾回收時(shí),也要求所有線程達(dá)到安全點(diǎn)后才能夠暫停并進(jìn)入STW從而開始進(jìn)行初始標(biāo)記、最終標(biāo)記等操作:

例如下面這段代碼:

Object o=new Object();

對(duì)應(yīng)匯編碼如下,可以看到0x00000000031ffb8f的call指令,它指明偏移量40-852處有一個(gè)普通對(duì)象指針Oop(Ordinary Object Pointer):

0x00000000031ffb80: mov    $0xf5,%edx
  0x00000000031ffb85: mov    %ecx,%ebp
  0x00000000031ffb87: mov    %rbx,0x28(%rsp)
  0x00000000031ffb8c: data16 xchg %ax,%ax
  0x00000000031ffb8f: callq  0x00000000030957a0  ; OopMap{[40]=Oop off=852}
                                                ;*new  ; - java.lang.String::<init>@58 (line 205)
                                                ; - java.lang.String::substring@52 (line 1933)
                                                ;   {runtime_call}

2. JVM如何讓線程跑到最近的安全點(diǎn)

對(duì)于安全點(diǎn)上的線程中斷策略,大體來說是有兩種:

  • 搶占式:當(dāng)需要進(jìn)入安全點(diǎn)時(shí),JVM會(huì)主動(dòng)掛起所有的用戶線程,如果線程未在安全點(diǎn)則等到該線程進(jìn)入安全點(diǎn)進(jìn)入安全點(diǎn)并完成中斷。這種做法最大的缺點(diǎn)就是時(shí)間不可控即很可能存在性能不穩(wěn)定亦或者吞吐量的波動(dòng),所以截至目前還有那款虛擬機(jī)采用搶占式的方式完成線程中斷。
  • 主動(dòng)式:這種方式是讓線程去維護(hù)一個(gè)標(biāo)志位,需要進(jìn)入安全點(diǎn)時(shí)修改該變量,用戶線程就會(huì)在合適的時(shí)機(jī)檢查這個(gè)變量值,如果這個(gè)值為真時(shí)就進(jìn)入安全點(diǎn)。

3. 線程什么時(shí)候需要進(jìn)入安全點(diǎn)

除了常見的垃圾回收標(biāo)記觸發(fā)STW使得所有線程需要進(jìn)入安全點(diǎn)以外,對(duì)應(yīng)的進(jìn)入安全點(diǎn)的時(shí)機(jī)還有:

  • 使用jstat、jmap、jstack等命令,為保證監(jiān)控堆棧信息的實(shí)時(shí)正確性,所有線程需要STW并進(jìn)入安全點(diǎn)暫停。
  • JDK8默認(rèn)情況下定時(shí)進(jìn)入安全點(diǎn),保證一些需要進(jìn)入安全點(diǎn)的操作能夠及時(shí)運(yùn)行。
  • JIT編譯代碼優(yōu)化例如:OSR(棧上替換即一種運(yùn)行時(shí)替換棧幀的技術(shù))或者去優(yōu)化即Bailout(將JIT編譯后的代碼回退,解釋器模式),因?yàn)榭赡艽嬖趫?zhí)行指令的變化,線程就需要進(jìn)入安全點(diǎn)。
  • java agent需要對(duì)類進(jìn)行增強(qiáng)導(dǎo)致類重新定義,需要修改類的相關(guān)信息,所以需要進(jìn)入安全點(diǎn)。
  • 高并發(fā)情況下,鎖升級(jí)機(jī)制會(huì)涉及偏向鎖撤銷,需要進(jìn)入STW檢查每個(gè)線程的使用狀態(tài),所以也需要進(jìn)入安全點(diǎn)。

4. JVM如何保證線程高效進(jìn)入安全點(diǎn)

我們以線程運(yùn)行JIT編譯好的代碼為例,它的設(shè)計(jì)與實(shí)現(xiàn)步驟為:

  • JVM初始化一個(gè)異常處理器,專門捕獲對(duì)應(yīng)的page fault缺頁(yè)中斷異常。
  • JIT編譯代碼期間,會(huì)基于我們上述的規(guī)則在特定位置插入一條精簡(jiǎn)的指令,作為安全點(diǎn)檢查。
  • VM線程通知當(dāng)前線程進(jìn)入安全點(diǎn),將線程內(nèi)部維護(hù)的內(nèi)存頁(yè)即polling page設(shè)置為不可讀。
  • 線程執(zhí)行這條機(jī)器碼指令發(fā)現(xiàn)內(nèi)存頁(yè)不可讀,觸發(fā)缺點(diǎn)中斷。
  • 異常處理器捕獲這個(gè)異常,線程進(jìn)入安全點(diǎn)。

對(duì)應(yīng)的我們也給出這段精簡(jiǎn)的匯編碼指令,即test %eax,0x160100 ; {poll}這段指令,這段指令本質(zhì)上就是執(zhí)行poll操作檢查安全點(diǎn),嘗試訪問線程內(nèi)存頁(yè)對(duì)應(yīng)地址為0x160100,如果發(fā)現(xiàn)不可訪問則觸發(fā)缺頁(yè)中斷進(jìn)入安全點(diǎn):

0x01b6d627: call   0x01b2b210         ; OopMap{[60]=Oop off=460}      
                                       ;*invokeinterface size      
                                       ; - Client1::main@113 (line 23)      
                                       ;   {virtual_call}      
 0x01b6d62c: nop                       ; OopMap{[60]=Oop off=461}      
                                       ;*if_icmplt      
                                       ; - Client1::main@118 (line 23)      
 0x01b6d62d: test   %eax,0x160100      ;   {poll}      
 0x01b6d633: mov    0x50(%esp),%esi      
 0x01b6d637: cmp    %eax,%esi

5. 如何設(shè)置安全點(diǎn)

而這個(gè)輪詢操作的合適的時(shí)機(jī)也就是觸發(fā)安全點(diǎn)的時(shí)機(jī),對(duì)于安全點(diǎn)的選定不能太過于頻繁導(dǎo)致過分增加內(nèi)存的負(fù)荷,如果進(jìn)入安全點(diǎn)的選定太少同樣也會(huì)導(dǎo)致線程無法及時(shí)進(jìn)入安全點(diǎn)而導(dǎo)致未能及時(shí)GC而OOM,所以我們對(duì)于安全點(diǎn)的選定一定要符合能夠讓程序長(zhǎng)時(shí)間的運(yùn)行為標(biāo)準(zhǔn):

無界循環(huán)或者大循環(huán):對(duì)于長(zhǎng)時(shí)間的while(true)或者以long類型為輪詢次數(shù)的for循環(huán),JVM會(huì)插入安全點(diǎn)保證循環(huán)能夠在需要停頓時(shí)及時(shí)停頓:

for (long i = 0; i < 10_0000_0000; i++) {
                counter.getAndAdd(1);
                //safe point
}
            
while (true){
                counter.getAndAdd(1);
                //safe point
 }

在執(zhí)行方法調(diào)用返回之前:

private boolean function() {
        //do something
        return true;
        //safe point 
    }

可能拋出異常的位置,例如下面這段代碼:

public static void main(String[] args)  {
        int result = 10 / 0;
    }

對(duì)應(yīng)的匯編碼如下,可以看到因?yàn)樗銛?shù)可能存在異常,它就在0x00000000033f0695設(shè)置了一個(gè)test安全點(diǎn)檢查:

0x00000000033f066c: mov    $0xa,%eax         ; 將被除數(shù)10加載到eax寄存器
0x00000000033f0671: mov    $0x0,%esi         ; 將除數(shù)0加載到esi寄存器(準(zhǔn)備觸發(fā)除零異常)
0x00000000033f0676: cmp    $0x80000000,%eax  ; 檢查被除數(shù)是否為Integer.MIN_VALUE(-2^31)
0x00000000033f067c: jne    0x00000000033f068d ; 如果不是則跳轉(zhuǎn)到常規(guī)除法流程
0x00000000033f0682: xor    %edx,%edx         ; 清零edx寄存器(特殊溢出處理路徑)
0x00000000033f0684: cmp    $0xffffffff,%esi  ; 檢查除數(shù)是否為-1(配合前面對(duì)MIN_VALUE的檢查)
0x00000000033f0687: je     0x00000000033f0690 ; 如果是-1則跳過除法(避免MIN_VALUE/-1溢出)
0x00000000033f068d: cltd                     ; 將eax符號(hào)位擴(kuò)展到edx(準(zhǔn)備64位被除數(shù))
0x00000000033f068e: idiv   %esi              ; 執(zhí)行有符號(hào)除法eax/esi(此處會(huì)觸發(fā)除零異常)
                                              ; 對(duì)應(yīng)Java代碼:int result = 10 / 0;
                                              ; 隱式異常處理分支:dispatches to 0x00000000033f069c
0x00000000033f0690: add    $0x30,%rsp        ; 調(diào)整棧指針(清理?xiàng)?0x00000000033f0694: pop    %rbp              ; 恢復(fù)調(diào)用者的基址指針
0x00000000033f0695: test   %eax,-0x28b059b(%rip) ; 安全點(diǎn)檢查:{poll_return}
                                              ; 檢查線程本地polling page是否可訪問
                                              ; 不可訪問則進(jìn)入安全點(diǎn)處理

6. 用一次GC解釋不同狀態(tài)的線程如何進(jìn)入safepoint

當(dāng)VM線程(JVM內(nèi)部的一種特殊的系統(tǒng)線程)需要觸發(fā)GC時(shí),它需要所有的線程都進(jìn)入安全點(diǎn),從而實(shí)現(xiàn)STW:

  • 線程正在運(yùn)行字節(jié)碼:這種情況也就是常規(guī)的情況,這解釋器會(huì)查看線程是否被設(shè)置為poll armed,如果為真則將其block阻塞。
  • 線程運(yùn)行JIT編譯好的代碼:JIT會(huì)在指定位置插入安全點(diǎn)檢查,如果需要進(jìn)入安全點(diǎn),JVM則會(huì)將線程內(nèi)部維護(hù)的內(nèi)存頁(yè)即polling page設(shè)置為不可讀,當(dāng)線程在安全點(diǎn)檢查時(shí)感知到這一點(diǎn)之后,就會(huì)直接將內(nèi)存block。
  • 線程正在運(yùn)行native代碼:VM線程不會(huì)等待該線程進(jìn)入阻塞狀態(tài),而是將線程設(shè)置為poll armed,當(dāng)線程執(zhí)行完成native代碼并返回時(shí)看到這個(gè)標(biāo)識(shí),如果還是需要停在safepoint,則會(huì)直接block阻塞。
  • 正在阻塞的線程,這種情況下線程就會(huì)一直阻塞,直到所有線程完成safepoint對(duì)應(yīng)的操作。
  • 正在執(zhí)行狀態(tài)切換,或者VM線程狀態(tài)(即執(zhí)行虛擬機(jī)線程正在工作的一種狀態(tài))的線程:這種情況下安全點(diǎn)檢查相關(guān)的代碼會(huì)不斷輪詢?cè)摼€程,直到該線程因?yàn)闋顟B(tài)切換或者鎖定safepoint checked monitor(安全點(diǎn)監(jiān)視鎖)完成阻塞。

需要注意這一小節(jié),筆者強(qiáng)調(diào)的是如何進(jìn)入安全點(diǎn)(各個(gè)線程如何進(jìn)入安全點(diǎn)),而不是何處插入安全點(diǎn)(插入安全點(diǎn)時(shí)機(jī)的選擇),讀者在閱讀本文時(shí)一定要梳理清楚插入安全時(shí)機(jī)設(shè)置和進(jìn)入安全點(diǎn)的時(shí)機(jī)設(shè)置的區(qū)別。

二、實(shí)踐-基于主線程休眠了解安全點(diǎn)的工作過程

1. 代碼示例

這段代碼比較簡(jiǎn)單,兩個(gè)子線程異步累加源自類,主線程休眠1s后輸出自己休眠的時(shí)長(zhǎng):

AtomicInteger counter = new AtomicInteger(0);

        Runnable runnable = () -> {
            for (int i = 0; i < 10_0000_0000; i++) {
                counter.getAndAdd(1);
            }
            System.out.println(Thread.currentThread().getName() + "運(yùn)行結(jié)束,counter:" + counter.get());
        };

        Thread t1 = new Thread(runnable, "t1");
        Thread t2 = new Thread(runnable, "t2");
        t1.start();
        t2.start();
        //主線程開始休眠
        long begin = System.currentTimeMillis();
        System.out.println("主線程開始休眠");
        Thread.sleep(1000);
        //休眠結(jié)束后,等待其他線程進(jìn)入安全點(diǎn)才開始結(jié)束休眠,所以輸出耗時(shí)19s
        long cost = System.currentTimeMillis() - begin;
        System.out.println("主線程結(jié)束休眠,耗時(shí):" + cost + "ms");

很多讀者可能認(rèn)為主線程打印的耗時(shí)差不多是1s,但事與愿違,輸出的結(jié)果竟然是30s:

主線程開始休眠
t1運(yùn)行結(jié)束,counter:2000000000
t2運(yùn)行結(jié)束,counter:2000000000
主線程結(jié)束休眠,耗時(shí):29956ms

由上述我們講解進(jìn)入,主線程調(diào)用native休眠返回后,程序因?yàn)槟撤N原因進(jìn)入全局安全點(diǎn),而兩個(gè)子線程因?yàn)槭怯薪缪h(huán)未能進(jìn)入安全點(diǎn),最終導(dǎo)致主線程長(zhǎng)時(shí)間等待兩個(gè)子線程進(jìn)入安全而導(dǎo)致休眠打印變長(zhǎng):

2. 基于日志印證執(zhí)行流程

對(duì)此我們基于-XX:+SafepointTimeout -XX:SafepointTimeoutDelay=2000參數(shù),查看進(jìn)入安全點(diǎn)超過2s后,主線程(包括其他未強(qiáng)調(diào)的用戶線程)在等待那些線程進(jìn)入安全點(diǎn)。

很明顯,從輸出結(jié)果來看所有線程都在等待兩個(gè)子線程進(jìn)入安全點(diǎn):

更進(jìn)一步,我們添加-XX:+PrintSafepointStatistics參數(shù),查看所有線程進(jìn)入安全點(diǎn)的耗時(shí),可以發(fā)現(xiàn):

  • JVM內(nèi)部非安全點(diǎn)的線程自旋等待進(jìn)入安全點(diǎn)時(shí)間和主線程休眠時(shí)間基本一致。
  • 同步所有線程進(jìn)入安全點(diǎn)時(shí)間block和上述休眠結(jié)束的耗時(shí)基本一致。

由此印證的問題根因:子線程未能及時(shí)進(jìn)入安全點(diǎn):

最后一個(gè)問題,這個(gè)觸發(fā)安全點(diǎn)的時(shí)機(jī)是什么呢?

通過-XX:+UnlockDiagnosticVMOptions -XX:+PrintFlagsFinal打印JVM參數(shù)可以發(fā)現(xiàn)下面這個(gè)參數(shù),查閱資料我們可以知曉該參數(shù)GuaranteedSafepointInterval,會(huì)默認(rèn)1s讓程序進(jìn)入一次全局安全點(diǎn):

所以我們最終得出根因,假設(shè)主線程在程序啟動(dòng)100ms進(jìn)入休眠,程序?qū)?yīng)的執(zhí)行步驟為:

  • 代碼執(zhí)行,JVM啟動(dòng),由于GuaranteedSafepointInterval參數(shù)配置為1000ms,所以在1s時(shí)需要設(shè)置一個(gè)安全點(diǎn)標(biāo)識(shí)位,讓所有用戶線程更新oopMap。
  • 主線程在1100ms時(shí)完成了1s的休眠準(zhǔn)備退出native的sleep,檢查安全點(diǎn)標(biāo)識(shí)為真因?yàn)槿表?yè)異常進(jìn)入安全點(diǎn)。
  • 兩個(gè)子線程因?yàn)橛薪缪h(huán)沒能進(jìn)入安全點(diǎn)繼續(xù)循環(huán)。
  • 主線程和其他用戶線程等待t1、t2完成循環(huán)。

3. 優(yōu)化思路

基于上述的分析,我們可以得出導(dǎo)致主線程休眠過長(zhǎng)的時(shí)間的主要原因:

  • 由于GuaranteedSafepointInterval定時(shí)觸發(fā)安全點(diǎn),導(dǎo)致主線程休眠結(jié)束后進(jìn)入安全點(diǎn)。
  • 主線程進(jìn)入安全點(diǎn)期間,子線程因?yàn)橛薪缪h(huán)而未能進(jìn)入安全點(diǎn)。

所以,基于原因1我們可以通過-XX:+UnlockDiagnosticVMOptions -XX:GuaranteedSafepointInterval=0強(qiáng)制關(guān)閉進(jìn)入安全點(diǎn),得到如下效果:

主線程開始休眠
主線程結(jié)束休眠,耗時(shí):1014ms

對(duì)于原因2,將有界循環(huán)改為long,讓JIT識(shí)別到這個(gè)大循環(huán)而插入安全點(diǎn):

三、關(guān)于安全點(diǎn)更進(jìn)一步的理解

1. 關(guān)于安全點(diǎn)的調(diào)優(yōu)建議

  • 高并發(fā)微服務(wù)的場(chǎng)景下建議關(guān)閉偏向鎖-XX:-UseBiasedLocking。
  • 避免有界循環(huán)可以在循環(huán)到一定次數(shù)時(shí),設(shè)置Thread.sleep(0)輔助進(jìn)入安全點(diǎn)。
  • int長(zhǎng)有界循環(huán)改為long,讓JIT為其插入安全點(diǎn)。
  • 優(yōu)化有界但是耗時(shí)長(zhǎng)的循環(huán)代碼。
  • 關(guān)閉定時(shí)進(jìn)入安全點(diǎn)-XX:+UnlockDiagnosticVMOptions -XX:GuaranteedSafepointInterval=0。

2. JDK11對(duì)于安全點(diǎn)的優(yōu)化

考慮到定時(shí)進(jìn)入安全點(diǎn)的非必要性和高并發(fā)場(chǎng)景下的阻塞風(fēng)險(xiǎn),jdk11默認(rèn)情況下已經(jīng)將該參數(shù)關(guān)閉,對(duì)此我們可以鍵入jinfo -flag GuaranteedSafepointInterval <pid>查看。

輸出結(jié)果如下,可以看到筆者將項(xiàng)目改為JDK11之后,對(duì)應(yīng)的參數(shù)值設(shè)置為0,即不定時(shí)進(jìn)入安全點(diǎn):

3. RocketMQ中對(duì)于安全點(diǎn)的優(yōu)化

基于上述的調(diào)優(yōu)建議,我們也給出RocketMQ對(duì)于安全點(diǎn)的優(yōu)化,以4.8.0版本為例,MappedFile為避免零拷貝循環(huán)寫入操作的耗時(shí),它會(huì)定時(shí)的調(diào)用Thread.sleep(0);讓線程調(diào)用native方法從而到達(dá)安全點(diǎn),保證需要時(shí)進(jìn)入STW完成GC:

public void warmMappedFile(FlushDiskType type, int pages) {
        long beginTime = System.currentTimeMillis();
        ByteBuffer byteBuffer = this.mappedByteBuffer.slice();
        int flush = 0;
        long time = System.currentTimeMillis();
        for (int i = 0, j = 0; i < this.fileSize; i += MappedFile.OS_PAGE_SIZE, j++) {
            byteBuffer.put(i, (byte) 0);
            //......

            // prevent gc
            //定期休眠,保證及時(shí)進(jìn)入安全點(diǎn),不阻塞其他需要進(jìn)入安全點(diǎn)的線程
            if (j % 1000 == 0) {
                log.info("j={}, costTime={}", j, System.currentTimeMillis() - time);
                time = System.currentTimeMillis();
                try {
                    Thread.sleep(0);
                } catch (InterruptedException e) {
                    log.error("Interrupted", e);
                }
            }
        }

       //......
    }

后續(xù)版本, 為了保證更加合理的進(jìn)入安全點(diǎn),這塊代碼也被直接優(yōu)化為long的長(zhǎng)循環(huán),讓JIT自行優(yōu)化,在合適的位置插入安全點(diǎn)保證線程能夠及時(shí)進(jìn)入安全點(diǎn)配合需要STW等工作:

責(zé)任編輯:趙寧寧 來源: 寫代碼的SharkChili
相關(guān)推薦

2025-06-30 07:10:00

JavaJVM線程

2025-07-09 07:30:00

2024-03-15 08:04:30

G1CMSJVM

2023-08-16 08:00:00

MSP安網(wǎng)絡(luò)安全

2023-11-09 09:38:50

自動(dòng)駕駛模型

2023-09-01 08:59:57

2024-02-04 09:00:00

向量查詢數(shù)據(jù)檢索MyScale

2020-02-24 21:43:36

avaJVM 級(jí)鎖線程安全

2024-12-30 08:03:08

2020-11-20 07:51:02

JavaSPI機(jī)制

2024-02-21 08:19:54

2023-07-14 12:28:07

JVM優(yōu)化操作

2023-06-26 07:57:49

2025-02-24 10:07:09

Redis節(jié)點(diǎn)遷移集群

2023-04-19 09:05:44

2023-07-31 07:48:43

Java內(nèi)存虛擬機(jī)

2023-04-24 14:54:09

JVM性能調(diào)優(yōu)

2023-01-08 13:46:49

2022-06-05 00:15:31

驗(yàn)證身份網(wǎng)絡(luò)

2024-08-07 08:22:27

點(diǎn)贊
收藏

51CTO技術(shù)棧公眾號(hào)

少妇高潮一区二区三区99| 91tv国产成人福利| 台湾色综合娱乐中文网| 在线观看一区不卡| 永久免费网站视频在线观看| 日日躁夜夜躁白天躁晚上躁91| 一区二区三区高清视频在线观看| 亚洲香蕉成视频在线观看| 亚洲一二三av| 永久免费毛片在线播放| 国产精品美女久久久久久| 97久草视频| 精品久久久久久久久久久久久久久久久久| 色综合五月天| 日韩成人在线电影网| 在线看免费毛片| 亚洲小少妇裸体bbw| 综合激情成人伊人| 欧美一区二区综合| 成人高潮片免费视频| 人禽交欧美网站| 久久露脸国产精品| 波兰性xxxxx极品hd| 香蕉视频一区| 精品国产亚洲在线| 亚洲18在线看污www麻豆| free性欧美| 亚洲六月丁香色婷婷综合久久 | 欧美日韩一级黄色片| 欧美一区高清| 日韩中文字幕在线精品| 免费在线观看成年人视频| 日韩激情综合| 欧美挠脚心视频网站| 麻豆av免费在线| а√在线中文在线新版| 亚洲精品第1页| www亚洲国产| av网站在线免费观看| 久久综合久久综合久久| 国产精品区一区二区三在线播放 | 欧美成人h版| 亚洲6080在线| 欧美一区二区激情| 亚洲电影视频在线| 亚洲激情成人在线| 久久久久久久免费视频| 免费日本一区二区三区视频| 中文字幕巨乱亚洲| 日韩亚洲不卡在线| 国产福利在线| 国产欧美1区2区3区| 美女精品国产| 男同在线观看| 国产调教视频一区| 手机在线观看国产精品| 国产女人在线观看| 欧美国产日韩一二三区| 日韩国产精品一区二区| eeuss影院在线播放| 中文字幕乱码久久午夜不卡| 亚洲精品成人三区| 欧美成人二区| 亚洲情趣在线观看| 国产高清不卡无码视频| 欧美aaaxxxx做受视频| 亚洲二区在线观看| 久久久999视频| 吞精囗交69激情欧美| 欧美专区在线观看一区| 色综合色综合色综合色综合| 欧美极品在线| 精品美女在线观看| 欧美深性狂猛ⅹxxx深喉| 香蕉人人精品| 少妇高潮久久久久久潘金莲| 久久精品日韩无码| 欧美激情综合| 91地址最新发布| 成人一二三四区| 精彩视频一区二区| 动漫美女被爆操久久久| 天堂v视频永久在线播放| 久久精品免视看| 欧美h视频在线观看| 国产乱妇乱子在线播视频播放网站| 亚洲国产婷婷综合在线精品| 国产精品免费入口| 日韩大陆av| 亚洲成人av在线| 91网站免费入口| 婷婷激情综合| 91av在线免费观看视频| 一区二区视频免费| 成人一级片在线观看| 日本黑人久久| a视频在线免费看| 黑人欧美xxxx| www.偷拍.com| 欧美人与物videos另类xxxxx| 久久久精品久久久久| 1级黄色大片儿| 久久精品国产免费看久久精品| 国产精品 日韩| 香蕉视频网站在线观看| 亚洲成人一区在线| 国产在线观看中文字幕| 麻豆国产欧美一区二区三区r| 中文字幕在线看视频国产欧美在线看完整 | 日本黄在线观看| 亚洲免费毛片网站| 日日摸天天爽天天爽视频| 精品精品视频| 色青青草原桃花久久综合| 免费在线观看黄色av| 日韩电影一区二区三区四区| 国产精品日韩高清| 黄色片免费在线观看| 色老汉一区二区三区| 佐佐木明希电影| 久久精品99久久无色码中文字幕| 97国产精品久久| 国产视频www| 国产嫩草影院久久久久| 国产97在线 | 亚洲| 深夜激情久久| 久久久精品久久久久| 波多野结衣一区二区三区在线| 99综合电影在线视频| 久久久久久久香蕉| 青青青国产精品| 亚洲视频在线观看| 亚洲av中文无码乱人伦在线视色| 成人av手机在线观看| 看全色黄大色大片| gogo大尺度成人免费视频| 中文字幕亚洲自拍| 中日韩av在线| 国产人伦精品一区二区| 国产精品免费观看久久| 麻豆精品少妇| 69**夜色精品国产69乱| 欧美一级性视频| 亚洲一区二区三区四区不卡| 永久看看免费大片| 亚洲精品一区二区妖精| 91精品国产综合久久久久久久久| a天堂中文在线88| 欧美在线观看你懂的| 男生草女生视频| 久久久成人网| 欧美凹凸一区二区三区视频| 午夜影院在线观看国产主播| 精品国产亚洲在线| 精品国产免费观看| 久久亚洲一区二区三区明星换脸| 成人综合视频在线| 亚洲妇女av| 奇米4444一区二区三区 | 在线视频欧美性高潮| 波多野结衣视频网址| 国产欧美日韩卡一| 亚洲精品20p| 亚洲精品一二三区区别| 999国产在线| √天堂8资源中文在线| 亚洲精品av在线| 五月婷婷激情视频| 国产精品免费视频观看| 天堂av2020| 黑丝一区二区| 欧美激情论坛| 精品国产黄a∨片高清在线| 久久久99久久精品女同性| 国产欧美熟妇另类久久久| 一区二区免费视频| 中文字幕一区三区久久女搜查官| 在线观看亚洲天堂| 日韩中文欧美| 91香蕉亚洲精品| 草莓视频丝瓜在线观看丝瓜18| 亚洲国产天堂久久综合网| 亚洲欧美自拍视频| 国产精品毛片大码女人| 国产人妻精品久久久久野外| 在线看片欧美| 日韩欧美激情一区二区| 精品午夜视频| 欧美亚洲在线观看| 日韩免费网站| 亚洲国产毛片完整版| 成人性教育视频在线观看| 国产a级片视频| 女生影院久久| 久久久成人的性感天堂| 欧美一区,二区| 欧美中文字幕不卡| 青青草国产在线观看| 久久尤物电影视频在线观看| 亚洲第一中文av| 欧美日本精品| 日韩免费av一区二区三区| 国产精品久一| 日本亚洲精品在线观看| 成人黄视频在线观看| 亚洲精品短视频| 亚洲系列第一页| 天天色 色综合| 中日韩一级黄色片| 久久午夜老司机| 成人做爰69片免费| 蜜臀va亚洲va欧美va天堂| 免费超爽大片黄| 98精品久久久久久久| 中文字幕日韩精品一区| 成人av在线不卡| 欧美一二区在线观看| 国产精品一区二区a| 国产原创一区| 日本一区二区三区在线播放| 免费在线播放电影| 久久精品中文字幕电影| 成人免费黄色网页| 日韩成人av网址| 农村少妇久久久久久久| 6080亚洲精品一区二区| 乱子伦一区二区三区| 欧美日韩精品国产| 国产一级片免费观看| 亚洲欧洲无码一区二区三区| 日本一级免费视频| xnxx国产精品| 日本少妇xxxx| 成人av一区二区三区| 中文在线字幕观看| 国产精品亚洲一区二区三区妖精| 亚洲77777| 免费观看在线综合色| 免费在线观看毛片网站| 国产精品亚洲综合色区韩国| av日韩一区二区三区| 女同性一区二区三区人了人一| 午夜精品视频在线观看一区二区| 亚洲精品中文字幕99999| 国产精品一国产精品最新章节| 亚洲1区在线| 99久久久久国产精品免费 | 国产精品久久久久久久久粉嫩av| 亚洲天堂视频在线播放| 欧美日韩三级| 欧美无砖专区免费| 国内精品亚洲| 夜夜添无码一区二区三区| 好吊日精品视频| 成人免费在线网| 亚洲黄网站黄| 99精品在线免费视频| 国产精品日本欧美一区二区三区| 黄色免费视频大全| 香蕉久久国产| 爱情岛论坛成人| 首页综合国产亚洲丝袜| 久久国产这里只有精品| 精品一区二区日韩| avtt中文字幕| 99re6这里只有精品视频在线观看| 最新版天堂资源在线| 99r国产精品| 国产免费无遮挡吸奶头视频| 国产精品美女一区二区在线观看| 亚洲不卡在线播放| 亚洲国产精品久久人人爱| 国产免费av一区二区| 日本高清不卡视频| 国产又粗又长又大视频| 日韩一级欧美一级| 三级小视频在线观看| 亚洲欧美国产精品久久久久久久| 国产视频精品久久| 久久久精品视频成人| jizz一区二区三区| 国产精品www色诱视频| 四虎成人精品一区二区免费网站| 97伦理在线四区| 夜夜春成人影院| 日本福利视频导航| 国产欧美日本| 女同激情久久av久久| 成人免费视频视频| 一级特黄曰皮片视频| 一区二区不卡在线播放 | 中文字幕丰满孑伦无码专区| 国产性做久久久久久| 久久久久久久久99| 欧美在线高清视频| 特黄视频在线观看| 久久九九精品99国产精品| 在线观看爽视频| 92国产精品视频| 国产不卡av一区二区| 久久男人资源站| 免费精品99久久国产综合精品| 欧洲熟妇的性久久久久久| 国产精品视频yy9299一区| 日韩欧美不卡视频| 制服丝袜国产精品| 国产乱子伦三级在线播放| 久久久亚洲成人| 亚洲欧美久久精品| 日韩精品另类天天更新| 亚洲国产免费看| 91香蕉视频免费看| 中文字幕不卡的av| 天天操夜夜操视频| 精品99一区二区| www.欧美日本韩国| 国产热re99久久6国产精品| 中国av一区| 黄色大片中文字幕| 国产福利91精品| sm捆绑调教视频| 欧美日韩一区二区电影| 精品视频一二三| 欧美在线视频免费| 清纯唯美亚洲经典中文字幕| av日韩在线看| 国产精品综合网| www.超碰在线观看| 在线91免费看| 欧美性天天影视| 国产精品一区二区三区久久久| 妖精视频一区二区三区免费观看| 国产一区二区三区小说| 国产精品 欧美精品| 国产在线免费av| 一本色道久久综合精品竹菊| 四虎永久在线精品免费网址| 久精品免费视频| 日韩欧美中文字幕一区二区三区 | 亚洲综合免费视频| 精品国产凹凸成av人网站| 日本在线www| 国产精品盗摄久久久| 女人抽搐喷水高潮国产精品| 免费看欧美一级片| 国产在线播放一区二区三区| 性色国产成人久久久精品| 欧美日韩电影在线| 中文字幕日本在线| 国产精品永久免费| 日韩理论电影| 久久久国产欧美| 中文字幕av一区二区三区免费看| 午夜影院免费在线观看| 亚洲天堂久久av| 欧美黄色三级| 亚洲一区3d动漫同人无遮挡 | 成人羞羞网站入口| 午夜国产一区二区三区| 国产日韩欧美精品一区| 懂色av蜜臀av粉嫩av分享吧最新章节| 亚洲视频免费一区| 日韩成人高清| 特级毛片在线免费观看| 久久99国产精品免费网站| 成人黄色免费网址| 这里只有精品免费| 自由的xxxx在线视频| 国产亚洲欧美另类一区二区三区| 亚洲承认在线| 99精品欧美一区二区| 欧洲视频一区二区| 国产精品四虎| 91精品国产自产在线老师啪| 91久久高清国语自产拍| 麻豆av免费看| 性久久久久久久久久久久| 国产区视频在线播放| 国产精品一区二区三区在线播放| 欧美 亚欧 日韩视频在线| 麻豆tv在线观看| 午夜精品福利一区二区三区蜜桃| 久久久资源网| 国产一区二区丝袜| 99精品国产在热久久婷婷| 制服丝袜第二页| 91精品国产一区二区三区蜜臀 | 人人九九精品视频| 日韩一级片免费视频| 久久久久久久精| 一卡二卡在线视频| 午夜精品一区二区三区在线视| 欧美黑白配在线| 成年人视频在线免费| 亚洲欧洲性图库| 天堂中文网在线| 国产精品亚洲综合天堂夜夜| 欧美成人精品| 日韩黄色中文字幕| 精品久久久久久最新网址|