精品欧美一区二区三区在线观看 _久久久久国色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技術棧公眾號

147欧美人体大胆444| 精品国偷自产在线| 久久综合久久色| 国产黄a三级三级三级av在线看 | 免费a级片在线观看| 欧美专区18| 欧美成人免费播放| 9.1成人看片| 精品视频在线观看网站| 日韩欧美aaa| www.国产亚洲| 97电影在线| jlzzjlzz亚洲日本少妇| 国产有码一区二区| 亚洲免费黄色网址| 亚洲欧美综合国产精品一区| 亚洲片国产一区一级在线观看| 一级做a免费视频| 亚洲成人人体| 亚洲午夜久久久久中文字幕久| 色噜噜一区二区| 日批免费在线观看| 国产精品99久久久久| 国产福利精品视频| 亚洲精品视频在线观看免费视频| 亚洲国产一区二区三区在线播放 | 91成人免费在线视频| 日韩精品一区二区在线视频 | 欧美激情2020午夜免费观看| 97在线观看免费视频| 欧美变态网站| 日韩午夜电影av| 色综合色综合色综合色综合| 欧美激情喷水| 欧美日韩国产在线| 欧美又粗又长又爽做受| 色图在线观看| 综合在线观看色| 亚洲蜜桃在线| 一区二区三区视频网站 | 亚洲成人黄色在线| 国产毛片久久久久久| 日韩欧乱色一区二区三区在线| 在线观看成人免费视频| av动漫免费看| 黑人巨大精品| 欧美亚一区二区| 一区二区三区国产免费| avav成人| 欧美亚洲丝袜传媒另类| 久久精品影视大全| 高清在线一区| 3d动漫精品啪啪一区二区竹菊| 在线观看av日韩| 国产香蕉久久| 欧美日韩第一区日日骚| 午夜免费看毛片| 亚洲青青一区| 欧美一区二区视频网站| 亚洲一级片免费观看| 久久综合给合| 亚洲福利视频久久| 国产午夜在线一区二区三区| 久久久久影视| 亚洲精品美女在线观看播放| 37p粉嫩大胆色噜噜噜| 国产探花在线精品| 色偷偷av一区二区三区乱| 日本激情视频一区二区三区| 亚洲国产精品综合久久久| 欧美老女人性视频| 日韩精品在线不卡| 亚洲欧美日韩一区在线观看| 日本精品视频在线| 中文字幕欧美人妻精品一区蜜臀| 麻豆精品视频在线观看视频| 亚洲一区美女视频在线观看免费| 亚洲国产中文字幕在线| 99国产精品国产精品毛片| 欧美日韩精品一区| 婷婷在线视频| 亚洲福中文字幕伊人影院| 国产特级淫片高清视频| 亚洲精品.com| 51精品久久久久久久蜜臀| 一级黄色电影片| 亚洲人成精品久久久 | 欧美v亚洲v| 色综合久久九月婷婷色综合| 亚洲36d大奶网| 亚洲精品一区二区三区中文字幕| 日韩av在线网页| 国产一区第一页| 亚洲天堂偷拍| 国产精品色悠悠| 午夜精品久久久久久久91蜜桃| 91天堂素人约啪| 中文字幕一区二区三区在线乱码| japanese色国产在线看视频| 欧美午夜不卡在线观看免费| 精品熟女一区二区三区| 日韩电影免费网址| 91po在线观看91精品国产性色| 正在播放木下凛凛xv99| 国产69精品久久久久777| 日本日本精品二区免费| 青春草在线视频| 欧美日韩亚洲另类| aa片在线观看视频在线播放| 亚洲欧洲中文字幕| 国产精品福利在线观看| 国产 日韩 欧美 精品| 国产精品少妇自拍| 久久精品国产精品亚洲色婷婷| 成人在线视频区| 一区二区成人av| 国产午夜在线播放| 国产精品一区二区男女羞羞无遮挡| 欧美日韩国产精品一区二区| 麻豆福利在线观看| 91精品国产综合久久国产大片| 色综合99久久久无码国产精品| 在线免费观看欧美| 成人国产1314www色视频| 日本视频在线免费观看| 欧日韩精品视频| 欧美狂猛xxxxx乱大交3| 国产精品外国| 精品免费二区三区三区高中清不卡 | 久久久人成影片一区二区三区在哪下载 | 亚洲制服欧美中文字幕中文字幕| 日韩欧美亚洲另类| 欧美美女一区| 日韩av高清不卡| 你懂的免费在线观看| 五月婷婷综合网| 白嫩情侣偷拍呻吟刺激| 欧美日本不卡| 亚洲直播在线一区| av网站在线看| 欧美本精品男人aⅴ天堂| 极品魔鬼身材女神啪啪精品| 免费一级片91| 亚洲欧美一区二区原创| 日韩中文在线播放| 中文字幕亚洲欧美一区二区三区| 国产一区免费看| 国产人妖乱国产精品人妖| 久久久久狠狠高潮亚洲精品| 一区二区三区日本久久久 | 黄色精品视频网站| 日韩视频在线免费| 国产美女免费视频| 一区二区三区在线免费播放| 农村末发育av片一区二区| 国产精品jizz在线观看美国| 国产精品精品软件视频| 草草在线视频| 国产偷国产偷亚洲清高网站| 销魂美女一区二区| 中文字幕av一区二区三区免费看 | 亚洲综合伊人| 欧美成人激情视频| 蜜臀久久99精品久久久| 欧美视频在线免费看| 国产免费一区二区三区网站免费| 蜜臀av一级做a爰片久久| 中文字幕av日韩精品| 日韩一区网站| 57pao精品| 在线看黄色av| 欧美成人bangbros| 日本视频在线观看免费| 久久精品欧美日韩| 欧美激情国内自拍| 亚洲国产mv| 日本精品一区二区| 麻豆视频久久| 欧美中文在线免费| 久久综合之合合综合久久| 日韩午夜小视频| 天码人妻一区二区三区在线看| 欧美国产一区在线| 一级黄色电影片| 日韩不卡一区二区| 国产乱子伦精品视频| 蜜桃一区二区三区| 91色视频在线导航| 色偷偷偷在线视频播放| xvideos亚洲人网站| 天天爽夜夜爽夜夜爽| 欧美日韩精品一区二区三区蜜桃| 久久免费视频精品| 国产精品美女久久久久久久| 中文在线观看免费视频| 秋霞电影一区二区| 日韩a级在线观看| 久久国产精品亚洲人一区二区三区| www.久久艹| 色999韩欧美国产综合俺来也| 97国产精品视频人人做人人爱| 成a人v在线播放| 亚洲第一精品夜夜躁人人躁| 亚洲天堂中文字幕在线| 欧美日韩另类在线| 久草成人在线视频| 亚洲欧洲av另类| 伊人网伊人影院| 不卡在线视频中文字幕| 久久精品亚洲天堂| 日韩av网站免费在线| 欧美色图色综合| 欧美三区在线| 一本一生久久a久久精品综合蜜| 欧美国产不卡| 国产99午夜精品一区二区三区| 久久久久伊人| 国产91精品网站| 午夜伦理福利在线| 欧美国产视频日韩| 国产高清一区二区三区视频| 国产午夜精品免费一区二区三区| 无码精品视频一区二区三区| 日韩美女天天操| 国产三级漂亮女教师| 欧美老人xxxx18| 中文字幕一区二区人妻痴汉电车 | 97在线视频人妻无码| 在线一区二区三区做爰视频网站| 亚洲第一在线播放| 午夜av区久久| 日韩毛片在线播放| 亚洲福中文字幕伊人影院| 免费一级片在线观看| 亚洲乱码精品一二三四区日韩在线| 日日碰狠狠添天天爽| 中文字幕久久午夜不卡| 亚洲色成人网站www永久四虎| 久久综合久色欧美综合狠狠| 国产精品成人无码专区| 成人aa视频在线观看| www.555国产精品免费| 成人午夜电影小说| 丰满岳乱妇一区二区| 高清成人在线观看| 中国xxxx性xxxx产国| 99热在这里有精品免费| 蜜臀aⅴ国产精品久久久国产老师| 国产精品自产自拍| 成人啪啪18免费游戏链接| 粉嫩在线一区二区三区视频| 麻豆精品国产传媒av| 9i在线看片成人免费| 男女黄床上色视频| 日本一区二区视频在线观看| 萌白酱视频在线| 亚洲三级电影全部在线观看高清| 欧美一区二区三区爽爽爽| 一个色妞综合视频在线观看| 久久久久久久九九九九| 欧美日韩国产激情| 无码人妻熟妇av又粗又大| 在线国产亚洲欧美| 国产又粗又大又爽视频| 日韩一区二区三区在线| 欧美一级在线免费观看| 亚洲精品自拍第一页| eeuss影院在线播放| www.亚洲成人| 678在线观看视频| 国产99久久精品一区二区永久免费| av在线日韩| 亚洲最大福利视频网| 黄色免费大全亚洲| 丝袜美腿玉足3d专区一区| 亚洲澳门在线| 狠狠97人人婷婷五月| 蜜臀av亚洲一区中文字幕| 少妇高潮一69aⅹ| 久久青草国产手机看片福利盒子 | 午夜精品久久一牛影视| jizz国产在线| 日韩一二三区不卡| 青青草免费在线| 爱福利视频一区| 天天综合av| 亚洲aaa激情| 亚洲理论电影| 亚洲一区 在线播放| 国产精品日本欧美一区二区三区| 在线黄色免费看| 91亚洲精华国产精华精华液| 国产精品suv一区二区88| 午夜久久久久久久久| 国产精品怡红院| 亚洲男人第一网站| 中文字幕资源网在线观看| 国产精品九九久久久久久久| 成人激情自拍| 裸体大乳女做爰69| 久久三级视频| 国产午夜在线一区二区三区| 1000部国产精品成人观看| 日本一区二区免费电影| 欧美成人女星排行榜| 欧美成年黄网站色视频| 日本精品久久久| 成人盗摄视频| 国产成人生活片| 蜜臀av一区二区三区| 国产成人精品无码免费看夜聊软件| 亚洲美女在线国产| 亚洲一卡二卡在线| 亚洲图片欧美日产| 天堂电影一区| 国产日韩精品一区观看| 午夜激情一区| 最新av免费在线观看| 国产午夜精品一区二区三区视频 | 免费av一区二区三区| 亚洲第一毛片| wwwww在线观看| 亚洲欧美日韩系列| 一本色道久久综合亚洲| 国产亚洲免费的视频看| 原纱央莉成人av片| 久久99精品久久久久久三级| 午夜久久99| 国内精品国产三级国产aⅴ久| 国产精品国产三级国产普通话99| 国产一区二区视频免费| 亚洲视频第一页| 欧美大片1688| 欧美成人蜜桃| 麻豆精品91| 午夜在线观看一区| 色欧美88888久久久久久影院| 午夜性色福利影院| 97在线看福利| 神马香蕉久久| 青青草原av在线播放| 久久天堂av综合合色蜜桃网| 免费看毛片网站| 亚洲最新在线视频| 福利一区二区| 国产一区一区三区| 国产精品91xxx| 精品少妇久久久| 亚洲第一男人av| 中文在线а√在线8| 欧美在线日韩精品| 老司机精品视频导航| 久久99久久99精品免费看小说| 欧美精品乱码久久久久久按摩| 超碰免费公开在线| 俄罗斯精品一区二区三区| 日韩一区二区久久| 男人的天堂官网| 91精品婷婷国产综合久久竹菊| 亚洲七七久久综合桃花剧情介绍| 国产精品9999久久久久仙踪林| 亚洲五月婷婷| 在线观看福利片| 欧美日韩精品一区视频| 日本小视频在线免费观看| 国产女主播一区二区三区| 久久精品麻豆| 熟女av一区二区| 欧美精品一区二区三区蜜桃视频| 国偷自产一区二区免费视频| 亚洲一区二区三区乱码| 国产凹凸在线观看一区二区| 日韩在线观看第一页| 在线观看国产精品淫| 免费精品一区| 免费成人午夜视频| 国产精品福利在线播放| 亚洲黄色片视频| 国产精品福利在线| 欧美午夜在线视频| 人妻视频一区二区| 欧美岛国在线观看| 久久人体大尺度| 中国女人做爰视频| 久久伊人中文字幕| 91精东传媒理伦片在线观看| 久久久亚洲成人| 欧美wwwww| 国产精品无码电影| 欧美一区二区视频在线观看| 欧美成人影院| 久久久久久久香蕉| 国产精品天干天干在观线| 人妻少妇精品无码专区久久| 国产精品久久网| 亚洲私人影院| 亚洲视频重口味| 精品亚洲男同gayvideo网站| 九色精品蝌蚪| youjizzxxxx18|