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

阿里二面:談談ThreadLocal的內存泄漏問題?

開發 前端
本文探討了ThreadLocal?的工作原理以及其內存泄漏問題及解決策略。ThreadLocal?通過為每個線程提供獨立的變量副本,實現多線程環境下的數據隔離。

引言

ThreadLocal在Java多線程編程中扮演著重要的角色,它提供了一種線程局部存儲機制,允許每個線程擁有獨立的變量副本,從而有效地避免了線程間的數據共享沖突。ThreadLocal的主要用途在于,當需要為每個線程維護一個獨立的上下文變量時,比如每個線程的事務ID、用戶登錄信息、數據庫連接等,可以減少對同步機制如synchronized關鍵字或Lock類的依賴,提高系統的執行效率和簡化代碼邏輯。

但是我們在使用ThreadLocal時,經常因為使用不當導致內存泄漏。此時就需要我們去探究一下ThreadLocal在哪些場景下會出現內存泄露?哪些場景下不會出現內存泄露?出現內存泄露的根本原因又是什么呢?如何避免內存泄露?

ThreadLocal原理

ThreadLocal的實現基于每個線程內部維護的一個ThreadLocalMap。

public class Thread implements Runnable {
     /* ThreadLocal values pertaining to this thread. This map is maintained
     * by the ThreadLocal class. */
    ThreadLocal.ThreadLocalMap threadLocals = null;
}

ThreadLocalMap是ThreadLocal類的一個靜態內部類,ThreadLocal本身不能存儲數據,它在作用上更像一個工具類,ThreadLocal類提供了set(T value)、get()等方法來操作ThreadLocalMap存儲數據。

public class ThreadLocal<T> {
    // ...
    public void set(T value) {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null)
            map.set(this, value);
        else
            createMap(t, value);
    }

    public T get() {
        Thread t = Thread.currentThread();
        ThreadLocalMap map = getMap(t);
        if (map != null) {
            ThreadLocalMap.Entry e = map.getEntry(this);
            if (e != null) {
                @SuppressWarnings("unchecked")
                T result = (T)e.value;
                return result;
            }
        }
        return setInitialValue();
    }

    ThreadLocalMap getMap(Thread t) {
        return t.threadLocals;
    }
    // ...
}

而ThreadLocalMap內部維護了一個Entry數據,用來存儲數據,Entry繼承了WeakReference,所以Entry的key是一個弱引用,可以被GC回收。Entry數組中的每一個元素都是一個Entry對象。每個Entry對象中存儲著一個ThreadLocal對象與其對應的value值。

static class ThreadLocalMap {

    static class Entry extends WeakReference<ThreadLocal<?>> {
            /** The value associated with this ThreadLocal. */
            Object value;

            Entry(ThreadLocal<?> k, Object v) {
                super(k);
                value = v;
            }
        }
}

關于弱引用的知識點,請參考:

而Entry數組中Entry對象的下標位置是通過ThreadLocal的threadLocalHashCode計算出來的。

private ThreadLocalMap(ThreadLocalMap parentMap) {
    Entry[] parentTable = parentMap.table;
    int len = parentTable.length;
    setThreshold(len);
    table = new Entry[len];

    for (Entry e : parentTable) {
        if (e != null) {
            @SuppressWarnings("unchecked")
            ThreadLocal<Object> key = (ThreadLocal<Object>) e.get();
            if (key != null) {
                Object value = key.childValue(e.value);
                Entry c = new Entry(key, value);
                // 通過key的threadLocalHashCode計算下標,這個key就是ThreadLocall對象
                int h = key.threadLocalHashCode & (len - 1);
                while (table[h] != null)
                    h = nextIndex(h, len);
                table[h] = c;
                size++;
            }
        }
    }
}

而從Entry數組中獲取對應key即ThreadLocal對應的value值時,也是通過key的threadLocalHashCode計算下標,從而可以快速的返回對應的Entry對象。

private Entry getEntry(ThreadLocal<?> key) {
// 通過key的threadLocalHashCode計算下標,這個key就是ThreadLocall對象
    int i = key.threadLocalHashCode & (table.length - 1);
    Entry e = table[i];
    if (e != null && e.get() == key)
        return e;
    else
        return getEntryAfterMiss(key, i, e);
}

在Thread中,可以存儲多個ThreadLocal對象。Thread、ThreadLocal、ThreadLocalMap以及Entry數組的關系如下圖:

圖片圖片

ThreadLocal在哪些場景下不會出現內存泄露?

當一個對象失去所有強引用,或者它僅被弱引用、軟引用、虛引用關聯時,垃圾收集器(GC)通常都能識別并回收這些對象,從而避免內存泄漏的發生。當我們在手動創建線程時,若將變量存儲到ThreadLocal中,那么在Thread線程正常運行的過程中,它會維持對內部ThreadLocalMap實例的引用。只要該Thread線程持續執行任務,這種引用關系將持續存在,確保ThreadLocalMap實例及其中存儲的變量不會因無引用而被GC回收。

圖片圖片

當線程執行完任務并正常退出后,線程與內部ThreadLocalMap實例之間的強引用關系隨之斷開,這意味著線程不再持有ThreadLocalMap的引用。在這種情況下,失去強引用的ThreadLocalMap對象將符合垃圾收集器(GC)的回收條件,進而被自動回收。與此同時,鑒于ThreadLocalMap內部的鍵(ThreadLocal對象)是弱引用,一旦ThreadLocalMap被回收,若此時沒有其他強引用指向這些ThreadLocal對象,它們也將被GC一并回收。因此,在線程結束其生命周期后,與之相關的ThreadLocalMap及其包含的ThreadLocal對象理論上都能夠被正確清理,避免了內存泄漏問題。

實際應用中還需關注ThreadLocalMap中存儲的值(非鍵)是否為強引用類型,因為即便鍵(ThreadLocal對象)被回收,如果值是強引用且沒有其他途徑釋放,仍可能導致內存泄漏。

ThreadLocal在哪些場景下會出現內存泄露?

在實際項目開發中,如果為每個任務都手動創建線程,這是一件很耗費資源的方式,并且在阿里巴巴的開發規范中也提到,不推薦使用手動創建線程,推薦使用線程池來執行相對應的任務。那么當我們使用線程池時,線程池中的線程跟ThrealLocalMap的引用關系如下:

圖片圖片

在使用線程池處理任務時,每一個線程都會關聯一個獨立的ThreadLocalMap對象,用于存儲線程本地變量。由于線程池中的核心線程在完成任務后不會被銷毀,而是保持活動狀態等待接收新的任務,這意味著核心線程與其內部持有的ThreadLocalMap對象之間始終保持著強引用關系。因此,只要核心線程存活,其所對應的ThreadLocal對象和ThreadLocalMap不會被垃圾收集器(GC)自動回收,此時就會存在內存泄露的風險。

出現內存泄露的根本原因

由上述ThreadLocalMap的結構圖以及ThreadLocalMap的源碼中,我們知道ThreadLocalMap中包含一個Entry數組,而Entry數組中的每一個元素就是Entry對象,Entry對象中存儲的Key就是ThreadLocal對象,而value就是要存儲的數據。其中,Entry對象中的Key屬于弱引用。

static class ThreadLocalMap {

    static class Entry extends WeakReference<ThreadLocal<?>> {
            /** The value associated with this ThreadLocal. */
            Object value;

            Entry(ThreadLocal<?> k, Object v) {
                super(k);
                value = v;
            }
        }
}

而對于弱引用WeakReference,在引用的對象使用完畢之后,即使內存足夠,GC也會對其進行回收。

關于弱引用的知識點,請參考:

圖片圖片

當Entry對象中的Key被GC自動回收后,對應的ThreadLocal被GC回收掉了,變成了null,但是ThreadLocal對應的value值依然被Entry引用,不能被GC自動回收。這樣就造成了內存泄漏的風險。

圖片圖片

在線程池環境下使用ThreadLocal存儲數據時,內存泄露的風險主要源自于線程生命周期管理及ThreadLocalMap內部結構的設計。由于線程池中的核心線程在完成任務后會復用,每個線程都會維持對各自關聯的ThreadLocalMap對象的強引用,這確保了只要線程持續存在,其對應的ThreadLocalMap就無法被垃圾收集器(GC)自動回收。

進一步分析,ThreadLocalMap內部采用一個Entry數組來保存鍵值對,其中每個條目的Key是當前線程中對應ThreadLocal實例的弱引用,這意味著當外部不再持有該ThreadLocal實例的強引用時,Key部分能夠被GC正常回收。然而,關鍵在于Entry的Value部分,它直接或間接地持有著強引用的對象,即使Key因為弱引用特性被回收,但Value所引用的數據卻不會隨之釋放,除非明確移除或者整個ThreadLocalMap隨著線程結束而失效。

所以,在線程池中,如果未正確清理不再使用的ThreadLocal變量,其所持有的強引用數據將在多個任務執行過程中逐漸積累并駐留在線程的ThreadLocalMap中,從而導致潛在的內存泄露風險。

ThreadLocal如何避免內存泄漏

經過上述ThreadLocal原理以及發生內存泄漏的分析,我們知道防止內存泄漏,我們一定要在完成線程內的任務后,調用ThreadLocal的remove()方法來清除當前線程中ThreadLocal所對應的值。其remove方法源碼如下:

public void remove() {
     ThreadLocalMap m = getMap(Thread.currentThread());
     if (m != null) {
         m.remove(this);
     }
 }

在remove()方法中,首先根據當前線程獲取ThreadLocalMap類型的對象,如果不為空,則直接調用該對象的有參remove()方法移除value的值。ThreadLocalMap的remove方法源碼如下:

private void remove(ThreadLocal<?> key) {
    Entry[] tab = table;
    int len = tab.length;
    int i = key.threadLocalHashCode & (len-1);
    for (Entry e = tab[i];
         e != null;
         e = tab[i = nextIndex(i, len)]) {
        if (e.get() == key) {
            e.clear();
            expungeStaleEntry(i);
            return;
        }
    }
}

由上述ThreadLocalMap中的set()方法知道ThreadLocal中Entry下標是通過計算ThreadLocal的hashCode獲得了,而remove()方法要找到需要移除value所在Entry數組中的下標時,也時通過當前ThreadLocal對象的hashCode獲的,然后找到它的下標之后,調用expungeStaleEntry將其value也置為null。我們繼續看一下expungeStaleEntry方法的源碼:

private int expungeStaleEntry(int staleSlot) {
    Entry[] tab = table;
    int len = tab.length;

    // expunge entry at staleSlot
    tab[staleSlot].value = null;
    tab[staleSlot] = null;
    size--;

    // Rehash until we encounter null
    Entry e;
    int i;
    for (i = nextIndex(staleSlot, len);
         (e = tab[i]) != null;
         i = nextIndex(i, len)) {
        ThreadLocal<?> k = e.get();
        if (k == null) {
            e.value = null;
            tab[i] = null;
            size--;
        } else {
            int h = k.threadLocalHashCode & (len - 1);
            if (h != i) {
                tab[i] = null;

                // Unlike Knuth 6.4 Algorithm R, we must scan until
                // null because multiple entries could have been stale.
                while (tab[h] != null)
                    h = nextIndex(h, len);
                tab[h] = e;
            }
        }
    }
    return i;
}

在expungeStaleEntry()方法中,會將ThreadLocal為null對應的value設置為null,同時會把對應的Entry對象也設置為null,并且會將所有ThreadLocal對應的value為null的Entry對象設置為null,這樣就去除了強引用,便于后續的GC進行自動垃圾回收,也就避免了內存泄露的問題。即調用完remove方法之后,ThreadLocalMap的結構圖如下:

圖片圖片

在ThreadLocal中,不僅僅是remove()方法會調用expungeStaleEntry()方法,在set()方法和get()方法中也可能會調用expungeStaleEntry()方法來清理數據。這種設計確保了即使沒有顯式調用remove()方法,系統也會在必要時自動清理不再使用的ThreadLocal變量占用的內存資源。

需要我們特別注意的是,盡管ThreadLocal提供了remove這種機制來防止內存泄漏,但它并不會自動執行相關的清理操作。所以為了確保資源有效釋放并避免潛在的內存泄露問題,我們應當在完成對ThreadLocal對象中數據的使用后,及時調用其remove()方法。我們最好(也是必須)是在try-finally代碼塊結構中,在finally塊中明確地執行remove()方法,這樣即使在處理過程中拋出異常,也能確保ThreadLocal關聯的數據被清除,從而有利于GC回收不再使用的內存空間,避免內存泄漏。

總結

本文探討了ThreadLocal的工作原理以及其內存泄漏問題及解決策略。ThreadLocal通過為每個線程提供獨立的變量副本,實現多線程環境下的數據隔離。其內部通過ThreadLocalMap與當前線程綁定,利用弱引用管理鍵值對。但是,如果未及時清理不再使用的ThreadLocal變量,可能導致內存泄漏,尤其是在線程池場景下。解決辦法包括在完成任務后調用remove方法移除無用數據。正確理解和使用ThreadLocal能夠有效提升并發編程效率,但務必關注潛在的內存泄漏風險。

責任編輯:武曉燕 來源: 碼農Academy
相關推薦

2022-10-18 08:38:16

內存泄漏線程

2018-10-25 15:24:10

ThreadLocal內存泄漏Java

2023-11-03 08:10:49

ThreadLoca內存泄露

2021-08-10 09:58:59

ThreadLocal內存泄漏

2022-05-09 14:09:23

多線程線程安全

2020-09-10 07:40:28

ThreadLocal內存

2025-04-01 05:22:00

JavaThread變量

2021-02-18 16:53:44

內存ThreadLocal線程

2024-02-21 08:00:55

WindowsDWM進程

2024-09-29 08:57:25

2023-11-28 12:25:02

多線程安全

2021-04-25 09:58:48

mmapJava面試

2021-03-17 15:54:32

IO零拷貝方式

2024-10-31 09:24:42

2024-01-30 10:12:00

Java內存泄漏

2017-01-05 19:34:06

漏洞nodejs代碼

2024-10-24 16:51:08

2021-12-28 14:53:47

Java編程語言

2010-09-26 15:38:33

JVM內存泄漏

2013-01-05 14:30:42

點贊
收藏

51CTO技術棧公眾號

在线观看中文字幕网站| 日韩免费在线观看av| 色哟哟一一国产精品| 两个人看的在线视频www| 美女www一区二区| 亚洲国产91精品在线观看| 亚洲欧美精品| 中文字幕第四页| 日韩一区二区三区精品| 国产精品久久久久久久久果冻传媒| 久久久久久久久久久成人| 最新中文字幕免费视频| 午夜影院免费视频| 欧美视频福利| 91精品啪在线观看国产60岁| 青青草成人网| 性无码专区无码| 久久激情av| 亚洲成人一区二区在线观看| 91在线网站视频| 少妇视频一区二区| 精品久久久网| 国产精品免费aⅴ片在线观看| 国产成人精品av在线| 国产老熟女伦老熟妇露脸| 亚洲电影视频在线| 国产精品一区二区在线观看不卡| 中文在线不卡视频| 波多野结衣天堂| 黄色小视频在线免费观看| 国产毛片久久| 日韩经典一区二区三区| 国产69精品久久久久999小说| 亚洲乱码在线观看| 在线成人亚洲| 亚洲国产黄色片| 妺妺窝人体色777777| 欧美一级在线免费观看| 一道本一区二区| 精品一区电影国产| 日韩精品免费播放| 国际av在线| 奇米一区二区三区| www.日韩av.com| 精品人妻一区二区三区免费| 日本一级理论片在线大全| 国产99一区视频免费| 久久久久日韩精品久久久男男| 男人添女人荫蒂国产| 俄罗斯一级**毛片在线播放| 成人黄色小视频在线观看| 98视频在线噜噜噜国产| 国产吞精囗交久久久| 黄色成人小视频| 亚洲色图一区二区三区| 高清视频一区二区三区| 六月丁香婷婷综合| 日韩欧美伦理| 欧美xxxx在线观看| 欧美一级片中文字幕| 午夜视频在线观看网站| 国产成人免费在线观看不卡| 97精品国产97久久久久久春色| 亚洲精品理论片| 欧美一区=区三区| 亚洲国产综合色| 日韩色妇久久av| 国产不卡精品视频| 亚洲欧美日本国产专区一区| 日韩在线视频导航| 中文视频在线观看| 成人午夜亚洲| 亚洲国产色一区| 亚洲免费视频一区| 午夜福利理论片在线观看| 免费美女久久99| 久久久久久久久久国产| 91禁男男在线观看| 麻豆一区一区三区四区| 欧美精品丝袜中出| 男人靠女人免费视频网站| 黄色免费在线看| 久久伊人中文字幕| 91传媒视频在线观看| 在线观看污污网站| 欧美午夜电影在线观看| 伊人久久免费视频| 中国极品少妇xxxx| 亚洲91在线| 色综合激情五月| 成人av在线不卡| 日本在线观看免费| 国产欧美视频一区二区| 国产在线一区二区三区四区| 国产精品久久久久久免费免熟| 国产日韩欧美一区在线| 色综合五月天导航| 亚洲人做受高潮| 久久91精品| 亚洲第一福利网| 黑人巨大猛交丰满少妇| 国产福利一区二区三区在线播放| 五月天中文字幕一区二区| 成年人免费观看的视频| freemovies性欧美| 国产亚洲一区字幕| 欧美日韩一区二区视频在线| 日本黄色一区二区三区| 国产成人午夜片在线观看高清观看| 国产精品狼人色视频一区| 中文字幕高清在线免费播放| 中文亚洲免费| 午夜精品久久久久久久久久久久久 | 岛国精品一区二区三区| 99tv成人影院| 欧美日本在线播放| 亚洲欧美激情网| 蜜臀国产一区| 欧美性极品少妇精品网站| 久久综合九色综合88i| 成人在线黄色电影| 婷婷综合另类小说色区| 成人午夜免费在线| 成人免费观看在线观看| 精品久久久久久中文字幕一区奶水 | 人妻精品一区一区三区蜜桃91 | 国产人成视频在线观看| 91久久精品无嫩草影院 | 国产精品探花在线播放| 欧美专区一区| 欧美岛国在线观看| 中文字幕天堂av| eeuss国产一区二区三区四区| 精品免费一区二区三区| 88av在线播放| 久久夜色电影| 亚洲色图偷窥自拍| 性爱在线免费视频| 亚洲国产不卡| 午夜精品久久久久久久久久久久 | 亚洲深深色噜噜狠狠爱网站| 成人97在线观看视频| 免看一级a毛片一片成人不卡| 狠狠入ady亚洲精品| 97超碰蝌蚪网人人做人人爽| 亚洲国产成人无码av在线| 久久久久国产一区二区| 国产精品久久久久久久9999| 国产又大又黄的视频| 国产福利精品一区| 久久精品国产99精品国产亚洲性色| 麻豆导航在线观看| 亚洲视频在线一区二区| 日韩人妻无码精品久久久不卡| 天堂中文最新版在线中文| 欧美日韩一区久久| 最新版天堂资源在线| 国产成人调教视频在线观看| 上原亚衣av一区二区三区| 久久久久久久久毛片| 国产精品久久久一区二区| 国产精品美腿一区在线看| 国产黄a三级三级看三级| 2023国产精品视频| 杨幂一区欧美专区| 久久影院午夜精品| 欧美日韩视频专区在线播放| 佐佐木明希电影| 欧美精品羞羞答答| 久久久久国产精品免费网站| 日本a级c片免费看三区| 国产91对白在线观看九色| 日韩av不卡在线播放| 午夜伦理在线视频| 日韩欧美中文字幕在线观看| 亚洲网中文字幕| 神马午夜久久| 欧美黄网免费在线观看| 中文字幕视频一区二区| av欧美精品.com| 日韩精品第1页| 国产成人精品123区免费视频| 精品国内二区三区| 欧美特黄一级片| 久久婷婷一区| 国产日韩一区欧美| 成人黄色在线电影| 欧美另类videos死尸| 日本少妇色视频| 狠狠爱成人网| 亚洲综合精品一区二区| 国产三级视频在线看| 亚洲高清不卡在线观看| 三级一区二区三区| 黑丝美女一区二区| 992tv在线成人免费观看| 国产黄色片网站| 日韩一区欧美小说| www亚洲成人| 中文字幕中文字幕精品| 98精品国产自产在线观看| 亚洲国产999| 亚洲欧美日韩国产一区二区三区 | 深夜成人影院| 亚洲国产黄色片| 国产无精乱码一区二区三区| 国内精品不卡在线| 在线免费一区| 欧美一区二区三区婷婷| 综合av色偷偷网| 超碰在线97观看| 久久久高清一区二区三区| 日韩精品―中文字幕| xxxx日韩| 午夜精品久久久久久久99热浪潮 | 日日噜噜夜夜狠狠久久丁香五月| 国产成人免费精品| 日韩中文字幕精品| 91福利免费视频| 国产精品久久三区| 中文字幕亚洲影院| 中文字幕一区二区精品区| 91社区国产高清| 在线观看午夜av| 精品国产精品网麻豆系列| 国产一级做a爰片在线看免费| 国产精品一级二级三级| 日韩人妻一区二区三区蜜桃视频| 国产 日韩 欧美| 久久久久国产精品www| 免费观看黄色一级视频| 欧美日韩在线第一页| 90岁老太婆乱淫| 日本不卡高清视频| 亚洲视频sss| 国产精品亚洲欧美日韩一区在线| 欧美猛少妇色xxxxx| 乱精品一区字幕二区| 欧美午夜宅男影院在线观看| xxxx日本黄色| 国产呦精品一区二区三区网站| 成人毛片100部免费看| y111111国产精品久久久| 欧美一区三区三区高中清蜜桃| 韩日视频在线| 欧美区一区二区三区| 国产亚洲小视频| 久久综合九色综合久久久精品综合| 久久久久久三级| 综合久久一区| 久久99九九| 成人在线不卡| 久久久欧美一区二区| 男男激情在线| 欧美一区二区在线视频| 日韩黄色a级片| 国产女主播视频一区二区| 午夜激情视频网| 亚洲专区一区二区三区| 福利网在线观看| 欧美爱爱网站| 成人免费直播live| 筱崎爱全乳无删减在线观看| 揄拍成人国产精品视频| 亚洲av无码国产精品永久一区| 精品女厕一区二区三区| 成年人二级毛片| 97成人超碰视| 超碰在线免费av| 久久婷婷影院| 妞干网视频在线观看| 日本精品三区| 精品午夜一区二区| 久久国产精品免费一区二区三区| 日本不卡免费高清视频| 污污的网站在线免费观看| 国产一区二区成人| 国产91麻豆视频| 欧美精品色综合| 加勒比在线一区| 亚洲超丰满肉感bbw| 亚洲区一区二区三| 中文字幕+乱码+中文字幕一区| 国产伦精品一区二区免费| 国产专区欧美精品| 午夜dv内射一区二区| 99热免费精品| 日韩极品视频在线观看| 99久久夜色精品国产亚洲96| 欧美美乳视频网站在线观看| 国产精品网在线观看| 91性高湖久久久久久久久_久久99| 成人欧美大片| 96精品视频在线| 久草在线资源站资源站| 成年人精品视频| 麻豆tv在线| 中文字幕亚洲综合| 国产在线你懂得| 日韩国产欧美精品在线| 日韩有码第一页| 精品久久久久久久人人人人传媒 | 日韩欧美一区二区免费| 国产一区二区三区视频免费观看 | 欧美成人第一页| 在线播放毛片| 色yeye香蕉凹凸一区二区av| 国产黄在线观看| 亚洲欧美日韩图片| 精品电影在线| 亚洲欧美日韩爽爽影院| 男同在线观看| 亚洲亚裔videos黑人hd| 国产在线中文字幕| 国产亚洲aⅴaaaaaa毛片| 国产一区二区影视| 亚洲最大中文字幕| av播放在线观看| 色偷偷av一区二区三区乱| 免费观看成人高潮| www.久久久久久.com| 男人的天堂在线视频免费观看 | 成人小视频免费看| 欧美国产禁国产网站cc| 99精品中文字幕| 亚洲精品精品亚洲| 日韩免费一二三区| 天天av天天翘天天综合网| 五月激情六月丁香| 欧美日韩一区二区三区不卡| 91 中文字幕| 欧美成人一区二区三区在线观看 | 麻豆映画在线观看| 亚洲国产精品第一区二区| 欧美日韩成人免费视频| 免播放器亚洲| 欧美黄色性生活| 国产精品资源在线| 一级欧美一级日韩片| 国产亚洲欧美在线| 成人一级黄色大片| 亚洲亚洲人成综合网络| 日韩人妻精品中文字幕| 欧美性大战久久久久久久| 国产精品久久久久久久一区二区 | 国产97免费视| 91欧美精品| 波多野结衣久草一区| 亚洲69av| 久久免费看毛片| 99国产精品久久久久久久| 99热手机在线| 国产激情一区二区三区四区 | 999精品网站| 久久电影网站中文字幕| 亚洲欧美高清在线| 国产精品乱码妇女bbbb| 久久亚洲av午夜福利精品一区| 欧美视频一二三| 999久久久久久| 日韩av在线免费看| 黄色在线免费看| 日本精品va在线观看| 精品一区二区三区四区五区| 欧美精品久久久| 欧美ab在线视频| 午夜视频在线瓜伦| 成人avav影音| 国产黄色的视频| 一本色道综合亚洲| 韩国av免费在线观看| 中文字幕亚洲色图| 小视频免费在线观看| 91传媒免费看| 色狮一区二区三区四区视频| 久久久久久久中文| 丰满亚洲少妇av| 永久免费看片视频教学| 色一情一伦一子一伦一区| 国产激情久久久久久熟女老人av| 亚洲欧美激情视频| www.8ⅹ8ⅹ羞羞漫画在线看| 国产在线精品一区免费香蕉| 夜夜躁狠狠躁日日躁2021日韩| www成人免费| 久久99国产精品尤物| 国产亚洲精品熟女国产成人| 五月激情综合婷婷| 丰满人妻一区二区| 久久九九国产精品怡红院| 日本精品裸体写真集在线观看| 久久另类ts人妖一区二区| 亚洲午夜激情在线| 欧美激情第四页| 国产精品网友自拍| 高潮毛片又色又爽免费| 日韩黄色高清视频| 色在线视频观看| 久久本道综合色狠狠五月| 亚洲高清自拍|