日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程语言 > java >内容正文

java

《深入理解java虚拟机》第2章 Java内存区域与内存溢出异常

發布時間:2025/3/15 java 24 豆豆
生活随笔 收集整理的這篇文章主要介紹了 《深入理解java虚拟机》第2章 Java内存区域与内存溢出异常 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Java與C++之間有一堵由內存動態分配和垃圾收集技術所圍成的“高墻”,墻外面的人想進去,墻里面的人卻想出來。

2.1 概述

https://blog.csdn.net/q5706503/article/details/84640762

對于從事C、C++程序開發的開發人員來說,在內存管理領域,他們既是擁有最高權力的“皇帝”又是從事最基礎工作的“勞動人民"一既擁有每一 個對象的“所有權”,又擔負著每一個對象生命開始到終結的維護責任。對于Java程序員來說,在虛擬機自動內存管理機制的幫助下,不再需要為每一個new操作去寫配對的de/free代碼,不容易出現內存泄漏和內存溢出問題,由虛擬機管理內存這一切看起來都很美好。不過,也正是因為Java程序員把內存控制的權力交給了Java虛擬機,一旦出現內存泄漏和溢出方面的問題,如果不了解虛擬機是怎樣使用內存的,那么排查錯誤將會成為一項異常艱難的工作。

本章是第二部分的第1章,筆者將從概念上介紹Java虛擬機內存的各個區域,講解這些區域的作用、服務對象以及其中可能產生的問題,這是翻越虛擬機內存管理這堵圍墻的第一步。

2.2運行時數據區域

Java虛擬機在執行Java程序的過程中會把它所管理的內存劃分為若千個不同的數據區域。這些區域都有各自的用途,以及創建和銷毀的時間,有的區域隨著虛擬機進程的啟動而存在,有些區域則依賴用戶線程的啟動和結束而建立和銷毀。根據《Java 虛擬機規范(Java SE 7版》的規定,Java 虛擬機所管理的內存將會包括以下幾個運行時數據區域,如圖2-1所示。

2.2.1程序計數器

程序計數器(Program Counter Register)是一塊較小的內存空間,它可以看作是當前線程所執行的字節碼的行號指示器。在虛擬機的概念模型里( 僅是概念模型,各種虛擬機可能會通過一些更高效的方式去實現),字節碼解釋器工作時就是通過改變這個計數器的值來選取下一條需要執行的字節碼指令,分支、循環、跳轉、異常處理、線程恢復等基礎功能都需要依賴這個計數器來完成。
由于Java虛擬機的多線程是通過線程輪流切換并分配處理器執行時間的方式來實現的,在任何一個確定的時刻,一個處理器(對于多核處理器來說是一個內核) 都只會執行一條線程中的指令。因此,為了線程切換后能恢復到正確的執行位置,每條線程都需要有一個獨立的程序計數器,各條線程之間計數器互不影響,獨立存儲,我們稱這類內存區域為“線程私有”的內存。如果線程正在執行的是-個Java方法,這個計數器記錄的是正在執行的虛擬機字節碼指令的地址;如果正在執行的是Native方法,這個計數器值則為空(Undefined)。 此內存區域是唯一一個在 Java虛擬機規范中沒有規定任何OutOfMemoryError情況的區域。

2.2.2 Java 虛擬機棧

與程序計數器-樣, Java虛擬機棧(Java Virtual Machine Stacks)也是線程私有的,它的生命周期與線程相同。虛擬機棧描述的是Java方法執行的內存模型:每個方法在執行的同時都會創建一個棧幀(Stack Frame9)用于存儲局部變量表、操作數棧、動態鏈接、方法出口等信息。每一個方法從調用直至執行完成的過程,就對應著一個棧幀在虛擬機棧中人棧到出棧的過程。?

經常有人把Java內存區分為堆內存(Heap)和棧內存(Stack), 這種分法比較粗糙,Java內存區域的劃分實際上遠比這復雜。這種劃分方式的流行只能說明大多數程序員最關注的、與對象內存分配關系最密切的內存區域是這兩塊。其中所指的“堆”筆者在后面會專門講述,而所指的“棧”就是現在講的虛擬機棧,或者說是虛擬機棧中局部變量表部分。
局部變量表存放了編譯期可知的各種基本數據類型(boolean、 byte、 char、 short、 int、float、long、 double)、 對象引用(reference 類型,它不等同于對象本身,可能是一個指向對象起始地址的引用指針,也可能是指向一個代表對象的句柄或其他與此對象相關的位置)和returnAddress類型(指向了一條字節碼指令的地址)。
其中64位長度的long和double類型的數據會占用2個局部變量空間(Slot), 其余的數據類型只占用1個。局部變量表所需的內存空間在編譯期間完成分配,當進入一個方法時,,這個方法需要在幀中分配多大的局部變量空間是完全確定的,在方法運行期間不會改變局部變量表的大小。

在Java虛擬機規范中,對這個區域規定了兩種異常狀況:如果線程請求的棧深度大于虛擬機所允許的深度,將拋出StackOverflowError異常;如果虛擬機棧可以動態擴展(當前大部分的Java虛擬機都可動態擴展,只不過Java虛擬機規范中也允許固定長度的虛擬機棧),如果擴展時無法申請到足夠的內存,就會拋出OutOfMemoryError異常。

2.2.3本 地方法棧

本地方法棧(Native Method Stack)與虛擬機棧所發揮的作用是非常相似的,它們之間的區別不過是虛擬機棧為虛擬機執行Java方法(也就是字節碼)服務,而本地方法棧則為虛擬機使用到的Native方法服務。在虛擬機規范中對本地方法棧中方法使用的語言、使用方式與數據結構并沒有強制規定,因此具體的虛擬機可以自由實現它。甚至有的虛擬機(譬如Sun HotSpot虛擬機)直接就把本地方法棧和虛擬機棧合二為一。與虛擬機棧一樣, 本地方法棧區域也會拋出StackOverflowError和OutOfMemoryError異常。

2.2.4 Java堆

對于大多數應用來說,Java 堆(Java Heap)是Java虛擬機所管理的內存中最大的一塊。Java堆是被所有線程共享的一塊內存區域,在虛擬機啟動時創建。此內存區域的唯- - 目的就是存放對象實例,幾乎所有的對象實例都在這里分配內存。這一點在Java虛擬機規范中的描述是:所有的對象實例以及數組都要在堆上分配e,但是隨著JIT編譯器的發展與逃逸分析技術逐漸成熟,棧上分配、標量替換優化技術將會導致一些微妙的變化發生,所有的對象都分配在堆上也漸漸變得不是那么“絕對”了。Java堆是垃圾收集器管理的主要區域,因此很多時候也被稱做“GC堆”(Garbage Collected Heap,幸好國內沒翻譯成“垃圾堆”)。從內存回收的角度來看,由于現在收集器基本都采用分代收集算法,所以Java堆中還可以細分為:新生代和老年代:再細致一點的有Eden空間、From Survivor空間、To Survivor空間等。從內存分配的角度來看,線程共享的Java堆中可能劃分出多個線程私有的分配緩沖區(Thread Local Allocation Buffer, TLAB)。不過無論如何劃分,都與存放內容無關,無論哪個區域,存儲的都仍然是對象實例,進一步劃分的目的是為了更好地回收內存,或者更快地分配內存。在本章中,我們僅僅針對內存區域的作用進行討論,Java 堆中的上述各個區域的分配、回收等細節將是第3章的主題。

根據Java虛擬機規范的規定,Java 堆可以處于物理上不連續的內存空間中,只要邏輯上是連續的即可,就像我們的磁盤空間- -樣。在實現時,既可以實現成固定大小的,也可以是可擴展的,不過當前主流的虛擬機都是按照可擴展來實現的(通過-Xmx和-Xms控制)。如果在堆中沒有內存完成實例分配,并且堆也無法再擴展時,將會拋出OutOfMemoryError異常。

2.2.5方法區

方法區(MethodArea)與Java堆一樣, 是各個線程共享的內存區域,它用于存儲已被虛擬機加載的類信息、常量、靜態變量、即時編譯器編譯后的代碼等數據。雖然Java虛擬機_規范把方法區描述為堆的一個邏輯部分,但是它卻有一個別名叫做Non-Heap (非堆),目的應該是與Java堆區分開來。

對于習慣在HotSpot虛擬機上開發、部署程序的開發者來說,很多人都更愿意把方法區稱為“永久代”(Permanent Generation),本質上兩者并不等價,僅僅是因為HotSpot虛擬機的設計團隊選擇把GC分代收集擴展至方法區,或者說使用永久代來實現方法區而已,這樣HotSpot的垃圾收集器可以像管理Java堆一樣管理這部分內存,能夠省去專門為方法區編寫內存管理代碼的工作。對于其他虛擬機(如BEA JRockit、IBM J9等)來說是不存在永久代的概念的。原則上,如何實現方法區屬于虛擬機實現細節,不受虛擬機規范約束,但使用永久代來實現方法區,現在看來并不是一個好主意,因為這樣更容易遇到內存溢出問題(永久代有-XX:MaxPermSize的上限,J9 和JRockit只要沒有觸碰到進程可用內存的上限,例如32位系統中的4GB,就不會出現問題),而且有極少數方法(例如String.intern())會因這個原因導致不同虛擬機下有不同的表現。因此,對于HotSpot虛擬機,根據官方發布的路線圖信息,現在也有放棄永久代并逐步改為采用Native Memory來實現方法區的規劃了e,在目前已經發布的JDK 1.7 的HotSpot中,已經把原本放在永久代的字符串常量池移出。

Java虛擬機規范對方法區的限制非常寬松,除了和Java堆一樣不需要連續的內存和可以選擇固定大小或者可擴展外,還可以選擇不實現垃圾收集。相對而言,垃圾收集行為在這個區域是比較少出現的,但并非數據進人了方法區就如永久代的名字-樣“永久”存在了。這區域的內存回收目標主要是針對常量池的回收和對類型的卸載,一般來說,這個區域的回收“成績"比較難以令人滿意,尤其是類型的卸載,條件相當苛刻,但是這部分區域的回收確實是必要的。在Sun公司的BUG列表中,曾出現過的若干個嚴重的BUG就是由于低版本的HotSpot虛擬機對此區域未完全回收而導致內存泄漏。根據Java虛擬機規范的規定,當方法區無法滿足內存分配需求時,將拋出OutOfMemoryError異常。

2.2.6運行時常量池

運行時常量池(Runtime Constant Pool)是方法區的一部分。Class 文件中除了有類的版本、字段、方法、接口等描述信息外,還有一項信息是常量池(Constant Pool Table),用于存放編譯期生成的各種字面量和符號引用,這部分內容將在類加載后進人方法區的運行時常量池中存放。Java虛擬機對Class文件每一部分 (自然也包括常量池)的格式都有嚴格規定,每一個字節用于存儲哪種數據都必須符合規范上的要求才會被虛擬機認可、裝載和執行,但對于運行時常量池,Java虛擬機規范沒有做任何細節的要求,不同的提供商實現的虛擬機可以按照自己的需要來實現這個內存區域。不過,一般來說, 除了保存Class文件中描述的符號引用外,還會把翻譯出來的直接引用也存儲在運行時常量池中。運行時常量池相對于Class文件常量池的另外一個重要特征是具備動態性,Java語言并不要求常量一定只有編譯期才能產生,也就是并非預置人Class文件中常量池的內容才能進人方法區運行時常量池,運行期間也可能將新的常量放人池中,這種特性被開發人員利用得比較多的便是String類的intern() 方法。既然運行時常量池是方法區的一部分,自然受到方法區內存的限制,當常量池無法再申請到內存時會拋出OutOfMemoryError異常。

2.2.7直 接內存

直接內存(DirectMemory)并不是虛擬機運行時數據區的一部分,也不是Java虛擬機規范中定義的內存區域。但是這部分內存也被頻繁地使用,而且也可能導致OutOfMemoryError異常出現,所以我們放到這里一起講解。在JDK 1.4 中新加入了NIO (New Input/Output)類,引入了一種基于通道(Channel)?與緩沖區(Buffer) 的I/O方式,它可以使用Native函數庫直接分配堆外內存,然后通過一個存儲在Java堆中的DirectByteBuffer對象作為這塊內存的引用進行操作。這樣能在一些場景中顯著提高性能,因為避免了在Java堆和Native堆中來回復制數據。顯然,本機直接內存的分配不會受到Java堆大小的限制,但是,既然是內存,肯定還是:
會受到本機總內存(包括RAM以及SWAP區或者分頁文件)大小以及處理器尋址空間的限制。服務器管理員在配置虛擬機參數時,會根據實際內存設置-Xmx等參數信息,但經常忽略直接內存,使得各個內存區域總和大于物理內存限制(包括物理的和操作系統級的限制),從而導致動態擴展時出現OutOfMemoryError異常。

2.3HotSpot虛擬機對象探秘

介紹完Java虛擬機的運行時數據區之后,我們大致知道了虛擬機內存的概況,讀者了解了內存中放了些什么后,也許就會想更進一步了解這些虛擬機內存中的數據的其他細節,譬如它們是如何創建、如何布局以及如何訪問的。對于這樣涉及細節的問題,必須把討論范圍限定在具體的虛擬機和集中在某-一個內存區域上才有意義。基于實用優先的原則,筆者以常用的虛擬機HotSpot和常用的內存區域Java堆為例,深人探討HotSpot虛擬機在Java堆中對象分配、布局和訪問的全過程。

2.3.1對象的創建

Java是一門面向對象的編程語言,在Java程序運行過程中無時無刻都有對象被創建出來。在語言層面上,創建對象(例如克隆、反序列化)通常僅僅是一個 new關鍵字而已,而在虛擬機中,對象(文中討論的對象限于普通Java對象,不包括數組和Class對象等)的創建又是怎樣-個過程呢?虛擬機遇到一條new指令時,首先將去檢查這個指令的參數是否能在常量池中定位到一個類的符號引用,并且檢查這個符號引用代表的類是否已被加載、解析和初始化過。如果沒有,那必須先執行相應的類加載過程,本書第7章將探討這部分內容的細節。

在類加載檢查通過后,接下來虛擬機將為新生對象分配內存。對象所需內存的大小在類加載完成后便可完全確定(如何確定將在2.3.2節中介紹),為對象分配空間的任務等同于把一塊確定大小的內存從Java堆中劃分出來。假設Java堆中內存是絕對規整的,所有用過的內存都放在一邊, 空閑的內存放在另一邊,中間放著一個指針作為分 界點的指示器,那所分配內存就僅僅是把那個指針向空閑空間那邊挪動一段與對象大小相等的距離,這種分配方式稱為“指針碰撞”(BumpthePointer)。如果Java堆中的內存并不是規整的,已使用的內存和空閑的內存相互交錯,那就沒有辦法簡單地進行指針碰撞了,虛擬機就必須維護-一個列表,記錄上哪些內存塊是可用的,在分配的時候從列表中找到一塊足夠大的空間劃分給對象實例,并更新列表上的記錄,這種分配方式稱為“空閑列表”(Free List)。選擇哪種分配方式由Java堆是否規整決定,而Java堆是否規整又由所采用的垃圾收集器是否帶有壓縮整理功能決定。因此,在使用Serial、ParNew 等帶Compact過程的收集器時,系統采用的分配算法是指針碰撞,而使用CMS這種基于Mark Sweep算法的收集器時,通常采用空閑列表。除如何劃分可用空間之外,還有另外一個需要考慮的問題是對象創建在虛擬機中是非常頻繁的行為,即使是僅僅修改一個指針所指向的位置,在并發情況下也并不是線程安全的,可能出現正在給對象A分配內存,指針還沒來得及修改,對象B又同時使用了原來的指針來分配內存的情況。解決這個問題有兩種方案,一種 是對分配內存空間的動作進行同步處理一實際 上虛擬機采用CAS配上失敗重試的方式保證更新操作的原子性:另-種是把內存分配的動作按照線程劃分在不同的空間之中進行,!即每個線程在Java堆中預先分配-小塊內存,稱為本地線程分配緩沖(Thread Local Allocation Buffer, TLAB)。 哪個線程要分配內存,就在哪個線程的TLAB上分配,只有TLAB用完并分配新的FLAB時,才需要同步鎖定。虛擬機是否使用TLAB,可以通過-XX:+/-UseTLAB參數來設定。內存分配完成后,虛擬機需要將分配到的內存空間都初始化為零值(不包括對象頭),如果使用TLAB,這一工作過程也可以提前至TLAB分配時進行。這一步操作保證了對象的實例字段在Java 代碼中可以不賦初始值就直接使用,程序能訪問到這些字段的數據類型所對應的零值。接下來,虛擬機要對對象進行必要的設置,例如這個對象是哪個類的實例、如何才能找到類的元數據信息、對象的哈希碼、對象的GC分代年齡等信息。這些信息存放在對象的對象頭(Object Header)之中。根據虛擬機當前的運行狀態的不同,如是否啟用偏向鎖等,對象頭會有不同的設置方式。關于對象頭的具體內容,稍后再做詳細介紹。在上面工作都完成之后,從虛擬機的視角來看,一個新的對象已經產生了,但從Java程序的視角來看,對象創建術剛剛開始一<init> 方法還沒有執行,所有的字段都還為零。所以,一般來說(由字節碼中是否跟隨invokespecial指令所決定),執行new指令之后會接著執行<init>方法,把對象按照程序員的意愿進行初始化,這樣一個真正可用的對象才算完全產生出來。
下面的代碼清單2=1是HotSpot虛擬機bytecodeInterpreter.cpp中的代碼片段(這個解釋器實現很少有機會實際使用,因為大部分平臺,上都使用模板解釋器;當代碼通過JIT編譯器執行時差異就更大了。不過,這段代碼用于了解HotSpot的運作過程是沒有什么問題的)。

代碼清單2-1 HotSpot 解釋器的代碼片段
//確保常量池中存放的是已解釋的類

if (!constants->tag_at(index).is_unresolved_klass()) {//斷言確保是klassOop和instanceKlassOop (這部分下一節介紹)oop entry = (klassOop) *constants->obj_at_addr(index) ; assert (entry->is_klass(), "Should be resolved klass") ;klassOop k_entry = (klassOop) entry;assert(k_entry->klass_part()->OoP_is_instance(), "Should be instanceKlass");instanceKlass* ik= (instanceKlass*) k_entry->klass_part();//確保對象所屬類型已經經過初始化階段if ( ik->is_initfalized() && ik->can_be_fastpath_allocated() ){//取對象長度size_t obj_size = ik->size_helper();oop result = NULL;//記錄是否需要將對象所有字段置零值bool need_zero = !ZeroTLAB;//是否在TLAB中分配對象if (UseTLAB) {result = (oop) THREAD->tlab().allocate (obj_size) ;}if (result==NULL) {need_zero = true;//1直接在eden中分配對象retry:HeapWord* compare_to = *Universe::heap()->top_addr() ;HeapWord* new_top = compare_to + obj_size;/* cmpxchg是x86中的CAS指令,這里是一個C++方法,通過CAS方式分配空間,如果并發失敗,轉到retry中重試,直至成功分配為止*/if (new_top <= *Universe::heap()->end_addr()) {if (Atomic::cmpxchg_ptr(new_top, Universe: :heap()->top_addr(), compare_to) != compare_to) {goto retry;}result = (oop) compare_to;}}if (result != NULL) {//如果需要,則為對象初始化零值if (need_zero ) {HeapWord* to_zero = (HeapWord*) result + sizeof (oopDesc) / oopSize;obj_size = sizeof (oopDesc) / oopSize;if(obj_size>0){memset (to_zero, 0,obj_size * HeapWordSize) ;}}//根據是否啟用偏向鎖來設置對象頭信息if (UseBiasedLocking) {result->set_mark (ik->prototype_header()) ;} else {result->set_mark (markOopDesc::prototype() ;}result->set_klass_gap(0) ;result->set_klass(k_entry) ;//將對象引用入棧,繼續執行下一條指令SET_STACK_OBJECT (result,0) ;UPDATE PC_AND_TOS_AND_CONTINUE(3, 1) ;}} }

?

2.3.2對象的內存布局

在HotSpot虛擬機中,對象在內存中存儲的布局可以分為3塊區域:對象頭( Header)、實例數據(Instance Data)和對齊填充( Padding).HotSpot虛擬機的對象頭包括兩部分信息,第一部分用于存儲對象自身的運行時數據,如哈希碼(HashCode)、 GC分代年齡、鎖狀態標志、線程持有的鎖、偏向線程ID、偏向時間戳等,這部分數據的長度在32位和64位的虛擬機(未開啟壓縮指針)中分別為32bit和64bit,官方稱它為“Mark Word"。對象需要存儲的運行時數據很多,其實已經超出了32位、64位Bitmap結構所能記錄的限度,但是對象頭信息是與對象自身定義的數據無關的額外存儲成本,考慮到虛擬機的空間效率,MarkWord被設計成一個非固定的數據結構以便在極小的空間內存儲盡量多的信息,它會根據對象的狀態復用自己的存儲空間。例如:在32位的HotSpot虛擬機中,如果對象處于未被鎖定的狀態下,那么Mark Word的32bit空間中的25bit用于存儲對象哈希碼,4bit 用于存儲對象分代年齡,2bit 用于存儲鎖標志位,1bit 固定為0,而在其他狀態(輕量級鎖定、重量級鎖定、GC標記、可偏向)下對象的存儲內容見表2-1

對象頭的另外- - 部分是類型指針,即對象指向它的類元數據的指針,虛擬機通過這個指針來確定這個對象是哪個類的實例。并不是所有的虛擬機實現都必須在對象數據上保留類型指針,換句話說,查找對象的元數據信息并不一一定要經過對象本身,這點將在2.3.3節討論。另外,如果對象是-一個Java數組,那在對象頭中還必須有一塊用于記錄數組長度的數據,因為虛擬機可以通過普通Java對象的元數據信息確定Java對象的大小,但是從數組的元數據中卻無法確定數組的大小。?

代碼清單2-2為HotSpot虛擬機markOop.cpp中的代碼(注釋)片段,它描述了32bit下Mark Word的存儲狀態。

接下來的實例數據部分是對象真正存儲的有效信息,也是在程序代碼中所定義的各種類型的字段內容。無論是從父類繼承下來的,還是在子類中定義的,都需要記錄起來。這部分的存儲順序會受到虛擬機分配策略參數(FieldsAllocationStyle)和字段在Java源碼中定義順序的影響。HotSpot 虛擬機默認的分配策略為longs/doubles、ints、 shorts/chars、 bytes/booleans、oops (Ordinary Object Pointers),從分配策略中可以看出,相同寬度的字段總是被分配到- -起。在滿足這個前提條件的情況下,在父類中定義的變量會出現在子類之前。如果CompactFields參數值為true (默認為true),那么子類之中較窄的變量也可能會插人到父類
變量的空隙之中。第三部分對齊填充并不是必然存在的,也沒有特別的含義,它僅僅起著占位符的作用。由于HotSpot VM的自動內存管理系統要求對象起始地址必須是8字節的整數倍,換句話說,就是對象的大小必須是8字節的整數倍。而對象頭部分正好是8字節的倍數(1 倍或者2倍),因此,當對象實例數據部分沒有對齊時,就需要通過對齊填充來補全。

2.3.3對象的訪問定位

建立對象是為了使用對象,我們的Java程序需要通過棧上的reference數據來操作堆上的具體對象。由于reference類型在Java虛擬機規范中只規定了一個指向對象的引用,并沒有定義這個引用應該通過何種方式去定位、訪問堆中的對象的具體位置,所以對象訪問方式也是取決于虛擬機實現而定的。目前主流的訪問方式有使用句柄和直接指針兩種。如果使用句柄訪問的話,那么Java堆中將會劃分出一塊內存來作為句柄池,reference中存儲的就是對象的句柄地址,而句柄中包含了對象實例數據與類型數據各自的具體地址信息,如圖2-2所示。

如果使用直接指針訪問,那么Java堆對象的布局中就必須考慮如何放置訪問類型數據的相關信息,而reference中存儲的直接就是對象地址,如圖2-3所示。?

?這兩種對象訪問方式各有優勢,使用句柄來訪問的最大好處就是reference中存儲的是穩定的句柄地址,在對象被移動(垃圾收集時移動對象是非常普遍的行為)時只會改變句柄中的實例數據指針,而reference本身不需要修改。使用直接指針訪問方式的最大好處就是速度更快,它節省了一次指針定位的時間開銷,由于對象的訪問在Java中非常頻繁,因此這類開銷積少成多后也是--項非常可觀的執行成本。就本書討論的主要虛擬機Sun HotSpot 而言,它是使用第二種方式進行對象訪問的,但從整個軟件開發的范圍來看,各種語言和框架使用句柄來訪問的情況也十分常見。

2.4實戰: OutOfMtemoryError 異常

在Java虛擬機規范的描述中,除了百 程序計數器外,虛擬機內存的其他幾個運行時區域都有發生OutOfMemoryError (下文稱OOM)異常的可能,本節將通過若干實例來驗證異常發生的場景(代碼清單2-3~代碼清單2-9的幾段簡單代碼),并且會初步介紹幾個與內存相關的最基本的虛擬機參數。本節內容的目的有兩個:第-一,通過代碼驗證Java虛擬機規范中描述的各個運行時區域
存儲的內容;第二,希望讀者在工作中遇到實際的內存溢出異常時,能根據異常的信息快速判斷是哪個區域的內存溢出,知道偉么樣的代碼可能會導致這些區域內存溢出,以及出現這些異常后該如何處理。下文代碼的開頭都注釋了執行時所需要設置的虛擬機啟動參數(注釋中“VM Args"后面跟著的參數),這些參數對實驗的結果有直接影響,讀者調試代碼的時候千萬不要忽略。如果讀者使用控制臺命令來執行程序,那直接跟在Java命令之后書寫就可以。如果讀者使用Eclipse IDE,則可以參考圖2-4在Debug/Run頁簽中的設置。

下文的代碼都是基于Sun公司的HotSpot虛擬機運行的,對于不同公司的不同版本的虛擬機,參數和程序運行的結果可能會有所差別。

2.4.1 Java 堆溢出

Java堆用于存儲對象實例,只要不斷地創建對象,并且保證GC Roots 到對象之間有可達路徑來避免垃圾回收機制清除這些對象,那么在對象數量到達最大堆的容量限制后就會產生內存溢出異常。代碼清單2-3中代碼限制Java堆的大小為20MB,不可擴展(將堆的最小值-Xms參數與最大值_Xmx參數設置為- -樣即可避免堆自動擴展),通過參數-X:+HeapDumpOnOutOfMemoryEror可
以讓虛擬機在出現內存溢出異常時Dump出當前的內存堆轉儲快照以便事后進行分析。

?

Java堆內存的OutOfMemoryError異常是實際應用中最常見的內存溢出異常情況。出現Java堆內存 溢出時,異常堆棧信息“java.lang.OutOfMemoryError”會跟隨進一步提示“Java heap space”。
要解決這個內存區域的異常,常規的處理方法是首先通過內存映像分析工具(如Eclipse Memory Analyzer)對Dump出來的堆轉儲快照進行分析。第一步首先應確認內存中導致OOM的對象是否是必 要的,也就是要先分清楚到底是出現了內存泄漏(Memory Leak)還是內存溢出(Memory Overflow)。圖2-5顯示了使用Eclipse Memory Analyzer打開的堆轉儲快照文件。


如果是內存泄漏,可進一步通過工具查看泄漏對象到GC Roots的引用鏈,找到泄漏對象是通過怎 樣的引用路徑、與哪些GC Roots相關聯,才導致垃圾收集器無法回收它們,根據泄漏對象的類型信息 以及它到GC Roots引用鏈的信息,一般可以比較準確地定位到這些對象創建的位置,進而找出產生內 存泄漏的代碼的具體位置。

如果不是內存泄漏,換句話說就是內存中的對象確實都是必須存活的,那就應當檢查Java虛擬機 的堆參數(-Xmx與-Xms)設置,與機器的內存對比,看看是否還有向上調整的空間。再從代碼上檢查 是否存在某些對象生命周期過長、持有狀態時間過長、存儲結構設計不合理等情況,盡量減少程序運 行期的內存消耗。
以上是處理Java堆內存問題的簡略思路,處理這些問題所需要的知識、工具與經驗是后面三章的 主題,后面我們將會針對具體的虛擬機實現、具體的垃圾收集器和具體的案例來進行分析,這里就先 暫不展開。
?

2.4.2 虛擬機棧和本地方法棧溢出

由于HotSpot虛擬機中并不區分虛擬機棧和本地方法棧,因此對于HotSpot來說,-Xoss參數(設置 本地方法棧大小)雖然存在,但實際上是沒有任何效果的,棧容量只能由-Xss參數來設定。關于虛擬 機棧和本地方法棧,在《Java虛擬機規范》中描述了兩種異常:
1)如果線程請求的棧深度大于虛擬機所允許的最大深度,將拋出StackOverflowError異常。
2)如果虛擬機的棧內存允許動態擴展,當擴展棧容量無法申請到足夠的內存時,將拋出 OutOfMemoryError異常。
《Java虛擬機規范》明確允許Java虛擬機實現自行選擇是否支持棧的動態擴展,而HotSpot虛擬機 的選擇是不支持擴展,所以除非在創建線程申請內存時就因無法獲得足夠內存而出現 OutOfMemoryError異常,否則在線程運行時是不會因為擴展而導致內存溢出的,只會因為棧容量無法 容納新的棧幀而導致StackOverflowError異常。
為了驗證這點,我們可以做兩個實驗,先將實驗范圍限制在單線程中操作,嘗試下面兩種行為是 否能讓HotSpot虛擬機產生OutOfMemoryError異常:
·使用-Xss參數減少棧內存容量。
結果:拋出StackOverflowError異常,異常出現時輸出的堆棧深度相應縮小。
·定義了大量的本地變量,增大此方法幀中本地變量表的長度。
結果:拋出StackOverflowError異常,異常出現時輸出的堆棧深度相應縮小。
首先,對第一種情況進行測試,具體如代碼清單2-4所示。
代碼清單2-4 虛擬機棧和本地方法棧測試(作為第1點測試程序)

/** * VM Args: -Xss128k * @author zzm */ public class JavaVMStackSOF {private int stackLength = 1;public void stackLeak() {stackLength++ ;stackLeak () ;}public static void main (String[] args) throws Throwable {JavaVMStackSOF oom = new JavaVMStackSOF() ;try {oom. stackLeak() ;} catch (Throwable e) {System. out.println("stack length:" + oom. stackLength) ;throw e ;}}}

對于不同版本的Java虛擬機和不同的操作系統,棧容量最小值可能會有所限制,這主要取決于操 作系統內存分頁大小。譬如上述方法中的參數-Xss128k可以正常用于32位Windows系統下的JDK 6,但 是如果用于64位Windows系統下的JDK 11,則會提示棧容量最小不能低于180K,而在Linux下這個值則 可能是228K,如果低于這個最小限制,HotSpot虛擬器啟動時會給出如下提示:

?我們繼續驗證第二種情況,這次代碼就顯得有些“丑陋”了,為了多占局部變量表空間,筆者不得 不定義一長串變量,具體如代碼清單2-5所示。
代碼清單2-5 虛擬機棧和本地方法棧測試(作為第2點測試程序)

/** * Qauthor zzm */ public class JavaVMStackSOF {private static int stackLength = 0;public static void test () {long unused1, unused2, unused3, unused4, unused5, unused6, unused7, unused8, unused9, unused10,unused11, unused12, unused13, unused14, unused15,unused16, unused17, unused18, unused19, unused20,unused21, unused22, unused23, unused24, unused25,unused26, unused27, unused28, unused29, unused30,unused31, unused32, unused33, unused34, unused35,unused36, unused37, unused38, unused39, unused40,unused41, unused42, unused43, unused44, unused45,unused46, unused47, unused48, unused49, unused50,unused51, unused52, unused53, unused54, unused55,unused56, unused57, unused58, unused59, unused60,unused61, unused62, unused63, unused64, unused65,unused66, unused67, unused68, unused69, unused70,unused71, unused72, unused73, unused74, unused75,unused76, unused77, unused78, unused79, unused80,unused81, unused82, unused83, unused84, unused85,unused86, unused87, unused88, unused89, unused90,unused91, unused92, unused93, unused94, unused95,unused96, unused97, unused98, unused99, unused100;stackLength ++;test() ;unused1 = unused2 = unused3 = unused4 = unused5 =unused6 = unused7 = unused8 = unused9 = unused10 =unused11 = unused12 = unused13 = unused14 = unused15 =unused16 = unused17 = unused18 = unused19 = unused20 =unused21 = unused22 = unused23 = unused24 = unused25 =unused26 = unused27 = unused28 = unused29 = unused30 = unused31 = unused32 = unused33 = unused34 = unused35 = unused36 = unused37 = unused38 = unused39 = unused40 = unused41 = unused42 = unused43 = unused44 = unused45 = unused46 = unused47 = unused48 = unused49 = unused50 = unused51 = unused52 = unused53 = unused54 = unused55 = unused56 = unused57 = unused58 = unused59 = unused60 = unused61 = unused62 = unused63 = unused64 = unused65 = unused66 = unused67 = unused68 = unused69 = unused70 = unused71 = unused72 = unused73 = unused74 = unused75 = unused76 = unused77 = unused78 = unused79 = unused80 = unused81 = unused82 = unused83 = unused84 = unused85 = unused86 = unused87 = unused88 = unused89 = unused90 = unused91 = unused92 = unused93 = unused94 = unused95 = unused96 = unused97 = unused98 = unused99 = unused100 = 0; } public static void main(String[] args) { try { test(); }catch (Error e){ System.out.println("stack length:" + stackLength); throw e; } } }

?運行結果:

stack length:5675 Exception in thread "main" java.lang.StackOverflowError at org.fenixsoft.oom. JavaVMStackSOF.leak(JavaVMStackSOF.java:27) at org.fenixsoft.oom. JavaVMStackSOF.leak(JavaVMStackSOF.java:28) at org.fenixsoft.oom. JavaVMStackSOF.leak(JavaVMStackSOF.java:28) ……后續異常堆棧信息省略

實驗結果表明:無論是由于棧幀太大還是虛擬機棧容量太小,當新的棧幀內存無法分配的時候, HotSpot虛擬機拋出的都是StackOverflowError異常。可是如果在允許動態擴展棧容量大小的虛擬機 上,相同代碼則會導致不一樣的情況。譬如遠古時代的Classic虛擬機,這款虛擬機可以支持動態擴展 棧內存的容量,在Windows上的JDK 1.0.2運行代碼清單2-5的話(如果這時候要調整棧容量就應該改 用-oss參數了),得到的結果是:

stack length:3716 java.lang.OutOfMemoryError at org.fenixsoft.oom. JavaVMStackSOF.leak(JavaVMStackSOF.java:27) at org.fenixsoft.oom. JavaVMStackSOF.leak(JavaVMStackSOF.java:28) at org.fenixsoft.oom. JavaVMStackSOF.leak(JavaVMStackSOF.java:28) ……后續異常堆棧信息省略

可見相同的代碼在Classic虛擬機中成功產生了OutOfMemoryError而不是StackOver-flowError異 常。如果測試時不限于單線程,通過不斷建立線程的方式,在HotSpot上也是可以產生內存溢出異常 的,具體如代碼清單2-6所示。但是這樣產生的內存溢出異常和棧空間是否足夠并不存在任何直接的關 系,主要取決于操作系統本身的內存使用狀態。甚至可以說,在這種情況下,給每個線程的棧分配的 內存越大,反而越容易產生內存溢出異常。
原因其實不難理解,操作系統分配給每個進程的內存是有限制的,譬如32位Windows的單個進程 最大內存限制為2GB。HotSpot虛擬機提供了參數可以控制Java堆和方法區這兩部分的內存的最大值,

那剩余的內存即為2GB(操作系統限制)減去最大堆容量,再減去最大方法區容量,由于程序計數器 消耗內存很小,可以忽略掉,如果把直接內存和虛擬機進程本身耗費的內存也去掉的話,剩下的內存 就由虛擬機棧和本地方法棧來分配了。因此為每個線程分配到的棧內存越大,可以建立的線程數量自 然就越少,建立線程時就越容易把剩下的內存耗盡,代碼清單2-6演示了這種情況。
代碼清單2-6 創建線程導致內存溢出異常
?

/** * VM Args:-Xss2M *(這時候不妨設大些,請在32位系統下運行) * @author zzm */ public class JavaVMStackOOM { private void dontStop() { while (true) { } } public void stackLeakByThread() { while (true) { Thread thread = new Thread(new Runnable() { @Override public void run() { dontStop(); } }); thread.start(); } } public static void main(String[] args) throws Throwable { JavaVMStackOOM oom = new JavaVMStackOOM(); oom.stackLeakByThread(); } }

注意 重點提示一下,如果讀者要嘗試運行上面這段代碼,記得要先保存當前的工作,由于在 Windows平臺的虛擬機中,Java的線程是映射到操作系統的內核線程上[1],無限制地創建線程會對操 作系統帶來很大壓力,上述代碼執行時有很高的風險,可能會由于創建線程數量過多而導致操作系統 假死。

出現StackOverflowError異常時,會有明確錯誤堆棧可供分析,相對而言比較容易定位到問題所 在。如果使用HotSpot虛擬機默認參數,棧深度在大多數情況下(因為每個方法壓入棧的幀大小并不是 一樣的,所以只能說大多數情況下)到達1000~2000是完全沒有問題,對于正常的方法調用(包括不能 做尾遞歸優化的遞歸調用),這個深度應該完全夠用了。但是,如果是建立過多線程導致的內存溢 出,在不能減少線程數量或者更換64位虛擬機的情況下,就只能通過減少最大堆和減少棧容量來換取 更多的線程。這種通過“減少內存”的手段來解決內存溢出的方式,如果沒有這方面處理經驗,一般比 較難以想到,這一點讀者需要在開發32位系統的多線程應用時注意。也是由于這種問題較為隱蔽,從 JDK 7起,以上提示信息中“unable to create native thread”后面,虛擬機會特別注明原因可能是“possibly out of memory or process/resource limits reached”。

2.4.3 方法區和運行時常量池溢出

由于運行時常量池是方法區的一部分,所以這兩個區域的溢出測試可以放到一起進行。前面曾經 提到HotSpot從JDK 7開始逐步“去永久代”的計劃,并在JDK 8中完全使用元空間來代替永久代的背景 故事,在此我們就以測試代碼來觀察一下,使用“永久代”還是“元空間”來實現方法區,對程序有什么 實際的影響。
String::intern()是一個本地方法,它的作用是如果字符串常量池中已經包含一個等于此String對象的 字符串,則返回代表池中這個字符串的String對象的引用;否則,會將此String對象包含的字符串添加 到常量池中,并且返回此String對象的引用。在JDK 6或更早之前的HotSpot虛擬機中,常量池都是分配 在永久代中,我們可以通過-XX:PermSize和-XX:MaxPermSize限制永久代的大小,即可間接限制其 中常量池的容量,具體實現如代碼清單2-7所示,請讀者測試時首先以JDK 6來運行代碼

代碼清單2-7 運行時常量池導致的內存溢出異常

/** * VM Args:-XX:PermSize=6M * -XX:MaxPermSize=6M * @author zzm */ public class RuntimeConstantPoolOOM { public static void main(String[] args) { // 使用Set保持著常量池引用,避免Full GC回收常量池行為 Set<String> set = new HashSet<String>(); // 在short范圍內足以讓6MB的PermSize產生OOM了 short i = 0; while (true) { set.add(String.valueOf(i++).intern()); } } }


?從運行結果中可以看到,運行時常量池溢出時,在OutOfMemoryError異常后面跟隨的提示信息 是“PermGen space”,說明運行時常量池的確是屬于方法區(即JDK 6的HotSpot虛擬機中的永久代)的 一部分。
而使用JDK 7或更高版本的JDK來運行這段程序并不會得到相同的結果,無論是在JDK 7中繼續使 用-XX:MaxPermSize參數或者在JDK 8及以上版本使用-XX:MaxMeta-spaceSize參數把方法區容量同 樣限制在6MB,也都不會重現JDK 6中的溢出異常,循環將一直進行下去,永不停歇[1]。出現這種變 化,是因為自JDK 7起,原本存放在永久代的字符串常量池被移至Java堆之中,所以在JDK 7及以上版 本,限制方法區的容量對該測試用例來說是毫無意義的。這時候使用-Xmx參數限制最大堆到6MB就能 夠看到以下兩種運行結果之一,具體取決于哪里的對象分配時產生了溢出:

關于這個字符串常量池的實現在哪里出現問題,還可以引申出一些更有意思的影響,具體見代碼 清單2-8所示。
代碼清單2-8 String.intern()返回引用的測試

public class RuntimeConstantPoolOOM { public static void main(String[] args) { String str1 = new StringBuilder("計算機").append("軟件").toString(); System.out.println(str1.intern() == str1); String str2 = new StringBuilder("ja").append("va").toString(); System.out.println(str2.intern() == str2); } }

?這段代碼在JDK 6中運行,會得到兩個false,而在JDK 7中運行,會得到一個true和一個false。產 生差異的原因是,在JDK 6中,intern()方法會把首次遇到的字符串實例復制到永久代的字符串常量池 中存儲,返回的也是永久代里面這個字符串實例的引用,而由StringBuilder創建的字符串對象實例在 Java堆上,所以必然不可能是同一個引用,結果將返回false。
而JDK 7(以及部分其他虛擬機,例如JRockit)的intern()方法實現就不需要再拷貝字符串的實例 到永久代了,既然字符串常量池已經移到Java堆中,那只需要在常量池里記錄一下首次出現的實例引 用即可,因此intern()返回的引用和由StringBuilder創建的那個字符串實例就是同一個。而對str2比較返 回false,這是因為“java”[2]這個字符串在執行String-Builder.toString()之前就已經出現過了,字符串常量 池中已經有它的引用,不符合intern()方法要求“首次遇到”的原則,“計算機軟件”這個字符串則是首次 出現的,因此結果返回true。
我們再來看看方法區的其他部分的內容,方法區的主要職責是用于存放類型的相關信息,如類 名、訪問修飾符、常量池、字段描述、方法描述等。對于這部分區域的測試,基本的思路是運行時產 生大量的類去填滿方法區,直到溢出為止。雖然直接使用Java SE API也可以動態產生類(如反射時的 GeneratedConstructorAccessor和動態代理等),但在本次實驗中操作起來比較麻煩。在代碼清單2-8里 筆者借助了CGLib[3]直接操作字節碼運行時生成了大量的動態類。
值得特別注意的是,我們在這個例子中模擬的場景并非純粹是一個實驗,類似這樣的代碼確實可 能會出現在實際應用中:當前的很多主流框架,如Spring、Hibernate對類進行增強時,都會使用到 CGLib這類字節碼技術,當增強的類越多,就需要越大的方法區以保證動態生成的新類型可以載入內存。另外,很多運行于Java虛擬機上的動態語言(例如Groovy等)通常都會持續創建新類型來支撐語 言的動態性,隨著這類動態語言的流行,與代碼清單2-9相似的溢出場景也越來越容易遇到。


代碼清單2-9 借助CGLib使得方法區出現內存溢出異常

方法區溢出也是一種常見的內存溢出異常,一個類如果要被垃圾收集器回收,要達成的條件是比 較苛刻的。在經常運行時生成大量動態類的應用場景里,就應該特別關注這些類的回收狀況。這類場 景除了之前提到的程序使用了CGLib字節碼增強和動態語言外,常見的還有:大量JSP或動態產生JSP 文件的應用(JSP第一次運行時需要編譯為Java類)、基于OSGi的應用(即使是同一個類文件,被不同 的加載器加載也會視為不同的類)等。
在JDK 8以后,永久代便完全退出了歷史舞臺,元空間作為其替代者登場。在默認設置下,前面 列舉的那些正常的動態創建新類型的測試用例已經很難再迫使虛擬機產生方法區的溢出異常了。不過 為了讓使用者有預防實際應用里出現類似于代碼清單2-9那樣的破壞性的操作,HotSpot還是提供了一 些參數作為元空間的防御措施,主要包括:
·-XX:MaxMetaspaceSize:設置元空間最大值,默認是-1,即不限制,或者說只受限于本地內存 大小。
·-XX:MetaspaceSize:指定元空間的初始空間大小,以字節為單位,達到該值就會觸發垃圾收集 進行類型卸載,同時收集器會對該值進行調整:如果釋放了大量的空間,就適當降低該值;如果釋放 了很少的空間,那么在不超過-XX:MaxMetaspaceSize(如果設置了的話)的情況下,適當提高該值。
·-XX:MinMetaspaceFreeRatio:作用是在垃圾收集之后控制最小的元空間剩余容量的百分比,可 減少因為元空間不足導致的垃圾收集的頻率。類似的還有-XX:Max-MetaspaceFreeRatio,用于控制最 大的元空間剩余容量的百分比。?

[1] 正常情況下是永不停歇的,如果機器內存緊張到連幾MB的Java堆都擠不出來的這種極端情況就不 討論了。 [2] 它是在加載sun.misc.Version這個類的時候進入常量池的。本書第2版并未解釋java這個字符串此前是 哪里出現的,所以被批評“挖坑不填了”(無奈地攤手)。如讀者感興趣是如何找出來的,可參考RednaxelaFX的知乎回答(https://www.zhihu.com/question/51102308/answer/124441115)。 [3] CGLib開源項目:http://cglib.sourceforge.net/。

2.4.4 本機直接內存溢出

直接內存(Direct Memory)的容量大小可通過-XX:MaxDirectMemorySize參數來指定,如果不 去指定,則默認與Java堆最大值(由-Xmx指定)一致,代碼清單2-10越過了DirectByteBuffer類直接通 過反射獲取Unsafe實例進行內存分配(Unsafe類的getUnsafe()方法指定只有引導類加載器才會返回實 例,體現了設計者希望只有虛擬機標準類庫里面的類才能使用Unsafe的功能,在JDK 10時才將Unsafe 的部分功能通過VarHandle開放給外部使用),因為雖然使用DirectByteBuffer分配內存也會拋出內存溢 出異常,但它拋出異常時并沒有真正向操作系統申請分配內存,而是通過計算得知內存無法分配就會 在代碼里手動拋出溢出異常,真正申請分配內存的方法是Unsafe::allocateMemory()。

代碼清單2-10 使用unsafe分配本機內存

?

?由直接內存導致的內存溢出,一個明顯的特征是在Heap Dump文件中不會看見有什么明顯的異常 情況,如果讀者發現內存溢出之后產生的Dump文件很小,而程序中又直接或間接使用了 DirectMemory(典型的間接使用就是NIO),那就可以考慮重點檢查一下直接內存方面的原因了。

2.5 本章小結

到此為止,我們明白了虛擬機里面的內存是如何劃分的,哪部分區域、什么樣的代碼和操作可能 導致內存溢出異常。雖然Java有垃圾收集機制,但內存溢出異常離我們并不遙遠,本章只是講解了各 個區域出現內存溢出異常的原因,下一章將詳細講解Java垃圾收集機制為了避免出現內存溢出異常都 做了哪些努力。

總結

以上是生活随笔為你收集整理的《深入理解java虚拟机》第2章 Java内存区域与内存溢出异常的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

亚洲 综合 国产 精品 | 人人爱爱人人 | 久久草草热国产精品直播 | 97在线视频免费播放 | 91av在线免费| 欧美91av | 国产精品嫩草在线 | 中文字幕精品一区二区精品 | av中文天堂 | 丁香视频全集免费观看 | 国产成人三级三级三级97 | 色久av | 日韩av电影手机在线观看 | 亚洲五月综合 | 超碰人人乐 | 成人黄色毛片 | 久久一级片 | 成人免费视频视频在线观看 免费 | 欧美在线你懂的 | 亚洲永久免费av | 亚洲免费永久精品国产 | 国产日产精品久久久久快鸭 | 92中文资源在线 | 久草91视频 | 欧美午夜一区二区福利视频 | 亚洲国产人午在线一二区 | 国产精品免费久久久久 | 99久久精品国产一区二区三区 | 婷婷六月天在线 | 国产一区二区在线免费 | 色天天综合网 | 久草男人天堂 | 激情导航| 成人一区电影 | 91麻豆精品久久久久久 | 久草在线中文视频 | 中文字幕制服丝袜av久久 | 天天操天天干天天综合网 | 97热在线观看 | 国产va在线 | 欧美综合久久 | 在线免费看黄网站 | 婷婷福利影院 | 欧美一二三专区 | 日狠狠| 亚洲国产av精品毛片鲁大师 | 久久一区二区三区日韩 | 青青草国产精品视频 | 不卡精品 | 亚洲精品美女久久久久网站 | 欧美日本不卡视频 | av 一区 二区 久久 | 91日韩免费 | 久久久久久国产精品久久 | 久久精品视频99 | 日韩专区av | 亚洲久草在线 | 成年人在线观看免费视频 | 亚洲精品中文字幕在线 | 91最新在线观看 | 五月天丁香综合 | a级国产乱理伦片在线观看 亚洲3级 | 日韩精品你懂的 | 91在线免费观看网站 | 欧美日韩在线精品一区二区 | 天天干天天干天天干 | 欧美在线观看视频一区二区三区 | 国产成人l区 | 中文字幕 国产视频 | 日韩国产精品久久久久久亚洲 | 欧美 日韩 国产 成人 在线 | 热久久免费视频 | 欧美精品v国产精品 | 中文字幕乱码在线播放 | 婷婷深爱网 | 精品亚洲免费视频 | 国产一区二区在线免费播放 | 久久久久久片 | 国产精品九九九九九九 | 丝袜少妇在线 | av福利网址导航 | 免费观看91 | 久久麻豆精品 | 国产亚洲精品美女久久 | 蜜桃视频色 | 日日草av | 亚洲国产日本 | 日韩精品免费在线播放 | 日韩精品一区二区三区三炮视频 | 午夜久久影视 | 精产嫩模国品一二三区 | 国产一区观看 | 日韩在线观看视频在线 | 国产午夜激情视频 | 亚洲午夜av电影 | 久久激情网站 | 国内精品美女在线观看 | 国产精品97| 奇米影视四色8888 | 亚洲免费av观看 | 国产不卡av在线播放 | 成人免费观看视频大全 | 国产 一区二区三区 在线 | 五月天综合色 | 亚洲少妇影院 | 国产高清综合 | 亚洲自拍偷拍色图 | 深夜福利视频在线观看 | 久久久婷| 欧美另类巨大 | 欧美午夜剧场 | 一区二区三区在线看 | 亚洲女同videos | 久久久久美女 | 欧美性生交大片免网 | 久久综合五月天 | 黄色99视频| 在线观看亚洲精品视频 | 国产99精品在线观看 | 伊人黄色网 | 亚洲国产精品视频 | 国产不卡网站 | 亚洲精品一区中文字幕乱码 | 麻豆精品传媒视频 | 日韩二区在线 | 人人揉人人揉人人揉人人揉97 | 欧美做受高潮电影o | 午夜国产福利视频 | 91视频91蝌蚪 | 国产精品激情偷乱一区二区∴ | 夜夜躁狠狠躁 | 亚洲欧美日韩精品久久久 | 国产视频每日更新 | 亚洲人成在线观看 | 日韩一区二区三区在线看 | 日本精品久久久久影院 | 日韩电影中文,亚洲精品乱码 | 人人爱人人舔 | 91精品色 | 亚洲天堂在线观看完整版 | 精品久久久一区二区 | 久久高视频 | 91网免费看 | 国产99久久精品一区二区永久免费 | 456免费视频 | 免费在线看成人av | 在线视频欧美亚洲 | 亚洲一区久久 | 久久黄色片 | 日日夜夜国产 | 国产精品嫩草55av | 日韩激情片在线观看 | 狠狠地操| 亚洲劲爆av| 免费a v观看 | 99久久er热在这里只有精品15 | 国产自产在线视频 | 亚洲精品免费在线观看视频 | 97超碰人 | 激情av网址 | 久久人视频 | 日日操操 | 一区二区视频播放 | 久久国产网 | 香蕉视频在线播放 | 黄网站免费大全入口 | 免费国产在线精品 | 久久亚洲影院 | 美女av免费看 | 久久欧美视频 | 日批视频 | 国色天香在线观看 | 久青草影院 | 久久综合狠狠综合久久狠狠色综合 | 波多野结衣在线观看一区二区三区 | 久久久久久久久久久久久国产精品 | av福利资源 | 在线观看免费av片 | 五月天色网站 | 操操操天天操 | 久久高清片| 草在线视频| 欧美精品在线一区二区 | 欧美网站黄色 | 久久婷综合| 一本色道久久精品 | 91亚洲精品久久久蜜桃网站 | 国产成人精品午夜在线播放 | 2022久久国产露脸精品国产 | 伊人手机在线 | 欧美人体xx | 国产精品资源在线观看 | 91一区在线观看 | 一区二区影院 | 91麻豆国产 | 在线电影日韩 | 日韩精品一卡 | 婷婷视频导航 | 蜜臀av性久久久久av蜜臀妖精 | 亚洲精欧美一区二区精品 | 一区二区三区不卡在线 | 国产高清视频在线播放 | 国产在线观看xxx | 福利视频精品 | 91精品一区二区三区蜜臀 | 亚洲黄色在线播放 | 国产精品久久久久av免费 | 美女一二三区 | 91在线视频免费观看 | 国产大陆亚洲精品国产 | 天堂麻豆| 韩国一区二区三区在线观看 | 婷婷精品国产欧美精品亚洲人人爽 | 色噜噜日韩精品一区二区三区视频 | a视频免费看 | 中文字幕在线观看一区二区 | 欧美另类重口 | 久久久久久高潮国产精品视 | 成人在线视频论坛 | 美女免费视频网站 | 婷婷新五月 | 成人午夜黄色 | 免费男女羞羞的视频网站中文字幕 | 丁香婷婷激情国产高清秒播 | 免费看黄在线看 | 日韩高清成人在线 | 欧美日韩一区二区视频在线观看 | 国产精品破处视频 | 黄色成人毛片 | 中文在线免费视频 | 国产专区一 | 麻豆国产在线播放 | 天堂av最新网址 | 国产麻豆精品95视频 | 国产综合福利在线 | 日本精品中文字幕 | 天堂久久电影网 | 国产精品无 | 国产精久久久久久妇女av | 亚洲mv大片欧洲mv大片免费 | 日韩av线观看 | 欧美乱码精品一区二区 | 久久精品视频网站 | 深夜精品福利 | 久久艹影院 | 国产男女无遮挡猛进猛出在线观看 | 日韩最新理论电影 | 日韩亚洲欧美中文字幕 | 亚洲九九精品 | 182午夜在线观看 | 久草视频在线新免费 | 国产又粗又猛又爽又黄的视频先 | 久热色超碰 | 久久精品1区2区 | 免费在线看成人av | 精品一区二区av | 91高清在线看 | 婷婷婷国产在线视频 | 丰满少妇久久久 | 99精品国产福利在线观看免费 | 99热官网 | 国产午夜三级一区二区三桃花影视 | 激情九九 | 免费观看完整版无人区 | 天天干天天做 | 日韩激情视频在线观看 | 国产又粗又猛又爽又黄的视频免费 | 久久久久中文字幕 | av7777777| 夜夜狠狠 | 黄色资源在线观看 | 精品国产99 | 久久99精品国产99久久 | 丁香六月婷婷开心婷婷网 | 国产精品18久久久久久久 | 国产一区二三区好的 | 日本高清dvd | 中文字幕免费高清在线 | 91av小视频 | 国产一区二区三区免费观看视频 | 日韩精品一区二区三区外面 | 999视频精品 | 日韩在线观看电影 | 四虎影视成人永久免费观看亚洲欧美 | 久久综合九色综合97婷婷女人 | 欧美在线视频精品 | www.午夜 | 久久精品久久综合 | 国产精品国产毛片 | 99精品在线播放 | 日韩高清免费在线观看 | 亚洲精品在线免费观看视频 | 国产乱码精品一区二区蜜臀 | av在线h | 中文av网 | 免费福利在线视频 | 丁香六月婷婷激情 | 精品国产一区二区三区久久久久久 | 久久精品日本啪啪涩涩 | 久久久一本精品99久久精品 | 7799av| 视频成人永久免费视频 | 色婷久久| 97在线视频免费看 | 久久99中文字幕 | 成人一区二区三区中文字幕 | 日本巨乳在线 | 99精品免费网 | 婷婷久月 | 国产又粗又猛又色又黄网站 | 91字幕 | 日日成人网| 在线看一区 | 色综合久久久久网 | 在线观看午夜av | 玖玖精品在线 | 天堂中文在线播放 | 免费福利片 | 精品国产精品国产偷麻豆 | 久久福利精品 | 国产三级精品三级在线观看 | 国产午夜三级一区二区三桃花影视 | 亚洲精品在线播放视频 | 精品视频不卡 | 国产一级做a爱片久久毛片a | 五月婷婷在线视频观看 | 8x8x在线观看视频 | 精品国产乱码久久久久 | 婷婷丁香社区 | 三级大片网站 | 97超碰影视 | 99精品国产福利在线观看免费 | 欧美片一区二区三区 | 国产99久久久国产精品免费看 | 精品1区2区 | 98超碰在线 | 国产精品综合久久久 | 亚洲狠狠操 | 久久字幕网| av视屏在线播放 | 色在线免费观看 | 精品一区二区免费视频 | 国产一区精品在线观看 | 日韩高清国产精品 | 五月天堂色 | 五月丁香 | 91免费的视频在线播放 | 久久久久久久久免费视频 | 91精品国产福利 | 久久久久一区二区三区四区 | 亚洲极色 | 中文字幕国产一区 | 波多野结衣在线视频免费观看 | 国产精品一二 | 国产一二三四在线观看视频 | 中文字幕最新精品 | 久久中文精品视频 | 福利一区在线 | www.色婷婷 | 91专区在线观看 | 人人看黄色| 人成在线免费视频 | 免费久久99精品国产 | 免费视频一级片 | 精品国产自在精品国产精野外直播 | a电影在线观看 | 狠狠色丁香婷婷综合久小说久 | 日韩大片在线 | 久久尤物电影视频在线观看 | 欧美成人h版电影 | 国产资源| 国产精品九九久久久久久久 | 国产美女视频 | 色就干| 亚洲另类xxxx | 精品国产视频在线观看 | 久久免费毛片视频 | 精品亚洲视频在线观看 | 久香蕉| 成人av电影在线播放 | 五月天视频网站 | 最新日韩在线 | 久久免费在线观看视频 | 美女免费视频网站 | 免费三级av | 色网站视频 | 91在线精品观看 | a√资源在线 | 久久只精品99品免费久23小说 | 九九热在线精品 | 欧美a√在线 | 久久久久久欧美二区电影网 | 天躁狠狠躁 | 天天爱天天干天天爽 | 亚洲一区黄色 | 狠狠操操| 久久午夜视频 | 国产一区在线免费观看 | 天天干亚洲 | 在线观看国产日韩欧美 | av在线播放快速免费阴 | 91日韩精品 | 香蕉色综合 | 久久久久国产精品一区二区 | 亚洲天堂网视频 | 亚洲精品视频网站在线观看 | 成年人免费在线 | 国产一区二区免费看 | 四虎在线视频免费观看 | 美女国内精品自产拍在线播放 | 久久免费的视频 | 97色婷婷成人综合在线观看 | 国产精品一区二区三区四区在线观看 | 中文字幕日韩国产 | 成人黄色电影在线播放 | zzijzzij亚洲日本少妇熟睡 | 国产一区二区在线免费 | 日韩高清无线码2023 | 久久精品视频免费 | 99精品电影 | 中文免费在线观看 | 成人97人人超碰人人99 | 日韩欧美91 | 在线观看免费国产小视频 | aa一级片 | 久久黄网站 | 色视频 在线 | www.成人久久 | 中文字幕在线人 | 天天爱天天 | 在线中文视频 | 免费国产一区二区 | 日韩电影在线视频 | 91网在线 | 色国产精品一区在线观看 | 在线观看免费黄色 | 色永久免费视频 | 黄色小说网站在线 | 欧美日韩一级视频 | 日韩精品欧美视频 | 欧美热久久 | 中文字幕一二 | 91精品国产麻豆国产自产影视 | 国产在线最新 | 亚洲h在线播放在线观看h | 欧美综合色在线图区 | 日韩精品三区四区 | 99re中文字幕 | 天天碰天天操 | 97av精品| 欧美人操人 | 一区二区三区在线免费观看视频 | 久久婷婷色综合 | 欧美成人性战久久 | 婷婷精品视频 | 热re99久久精品国产99热 | 国产视频18 | 久久综合亚洲鲁鲁五月久久 | 91黄色在线看 | 国内小视频在线观看 | 久久激情综合网 | 午夜精品久久久久久久99热影院 | 91视视频在线直接观看在线看网页在线看 | 久久久久久久久精 | av高清在线 | 91精品国产亚洲 | 一区免费视频 | 日b视频在线观看网址 | 国产成人精品久久亚洲高清不卡 | 日韩高清观看 | 国产成人精品一区二区三区 | 精品国产成人av在线免 | 97精品国产一二三产区 | 亚洲激情中文 | 亚洲最大激情中文字幕 | 人人爽人人乐 | 久久人人艹 | 日韩在线视频看看 | 欧美日韩伦理一区 | 日韩国产精品久久久久久亚洲 | 精品久久九九 | 日韩在线免费看 | 天天干天天玩天天操 | av成人在线观看 | 久久精品三级 | 亚洲国产精品第一区二区 | 国产精品热视频 | 黄色日本免费 | 国产精品久久久久久一区二区三区 | 综合久久网站 | 日韩色高清| 成人av影视观看 | 国产成人三级一区二区在线观看一 | 狠狠地操 | 美女精品网站 | 欧美日韩不卡一区二区 | 国产欧美在线一区 | 日韩视频在线观看免费 | 中文字幕乱码亚洲精品一区 | 欧美日韩视频精品 | 91精品久久久久久久久 | 免费人人干 | 在线黄色av | 国产精品av免费在线观看 | 视频国产区 | 水蜜桃亚洲一二三四在线 | 国产视频在线观看一区 | 色www精品视频在线观看 | 91.麻豆视频| 91精品999 | 99色在线播放 | 亚洲欧美日韩在线看 | 天堂在线成人 | va视频在线观看 | 欧美精品乱码久久久久久 | 日韩成人免费在线观看 | 中文字幕av在线不卡 | 成人福利av| 一区二区 不卡 | 激情久久综合网 | 免费大片av | 黄色成人av网址 | 91尤物在线播放 | 亚洲精品av在线 | 天天操天天曰 | 在线播放国产精品 | 国产精品一区二区三区99 | 伊人午夜 | 成人app在线播放 | 久艹视频免费观看 | 青草视频在线看 | 国产精品一区电影 | 国产精品 国产精品 | 日韩免费在线一区 | 国产成人a v电影 | 在线视频中文字幕一区 | 99久久婷婷国产一区二区三区 | 国产精品一区二区三区电影 | 在线中文字母电影观看 | 久久国产精品久久w女人spa | 国产高清视频网 | 欧洲性视频 | 深爱激情开心 | 色婷五月 | 免费福利在线视频 | 国产精品va | 日韩精品一区二区三区在线播放 | 亚洲国内精品在线 | 91精品视频在线观看免费 | 夜夜操综合网 | 久久毛片高清国产 | 国产成人精品在线观看 | 国产高清福利在线 | av网址aaa| 欧美俄罗斯性视频 | 久久久久网址 | 日韩大片在线免费观看 | 亚洲国产成人高清精品 | 日日干日日 | 日韩av影视在线观看 | 久久久免费看片 | 天躁狠狠躁 | 丁香六月中文字幕 | 中文字幕在线视频一区二区三区 | 色婷婷88av视频一二三区 | 激情综合站| 亚洲网站在线看 | 97av在线视频免费播放 | av不卡免费在线观看 | 欧美少妇xxx | 在线观看亚洲精品 | 亚洲成人资源网 | 久久久久久蜜av免费网站 | 手机成人在线电影 | 久久99视频免费观看 | 欧美性超爽| 国产高清在线免费观看 | 黄色三级免费片 | 五月婷婷丁香综合 | 色老板在线视频 | 黄色日视频 | 日韩免费在线播放 | av大片免费在线观看 | 国产午夜精品一区二区三区欧美 | 三级黄色片子 | 国产99re| 日韩手机在线 | 婷婷av色综合 | 国产夫妻性生活自拍 | 免费在线成人av电影 | 久久免费视频2 | 中文字幕在线观看第三页 | 不卡av在线 | 久久成人黄色 | 成人资源网 | 色国产精品一区在线观看 | 人人玩人人添人人澡97 | 免费视频一区二区 | 日韩在线中文字幕 | 碰超人人| 国产成a人亚洲精v品在线观看 | 国产男女爽爽爽免费视频 | 日韩欧美视频一区二区 | av免费高清观看 | 色综合久久久久综合99 | 久草视频2| 精品国产中文字幕 | 成人a视频片观看免费 | 国产精品久久久久一区二区三区 | 日韩三级视频在线观看 | 91九色网站| 四虎国产精品成人免费影视 | 99热99 | www.色就是色| 亚洲成人精品久久 | 国产精品无 | bbb搡bbb爽爽爽 | 国产成人精品av在线观 | 干干干操操操 | 久久大片网站 | 国产一区播放 | 国产一二三四在线视频 | 国产精品成人自产拍在线观看 | 草久久久久久久 | 亚洲天天综合网 | 亚洲一级二级三级 | 天天射天天干 | 国产亚洲精品久久久久久无几年桃 | 久青草视频在线观看 | 国产资源中文字幕 | 一区二区伦理 | 91香蕉视频| 开心婷婷色| 国产.精品.日韩.另类.中文.在线.播放 | 欧美日韩中文视频 | 国产不卡av在线 | 麻豆果冻剧传媒在线播放 | 久久亚洲区 | 国产精品一区二区在线 | 欧美一区二区三区四区夜夜大片 | 五月婷婷综合久久 | 国内精品一区二区 | 亚洲精品在线免费看 | 日本一区二区免费在线观看 | 韩国av一区二区三区在线观看 | 国产精品电影一区 | 九九视频免费观看视频精品 | 国产精品嫩草影院123 | www.日本色| 天天色中文 | 日韩二区三区 | 成人在线播放免费观看 | 日韩久久久 | 精品欧美一区二区三区久久久 | 国内外成人免费在线视频 | 亚洲免费视频在线观看 | 久久久男人的天堂 | 五月婷婷一区 | 亚洲精品综合久久 | 天天爱天天操天天干 | 一区二区三区日韩在线 | 丁香婷婷在线观看 | 亚洲视频分类 | 日本最新高清不卡中文字幕 | 中文字幕精品三级久久久 | 日韩av免费观看网站 | 日韩二区在线 | av在线永久免费观看 | 天天视频色版 | 成人免费在线播放视频 | 久久欧洲视频 | 欧美另类老妇 | 日日夜夜精品 | 日韩一二区在线观看 | 一区二区三区免费播放 | 国产精品99在线观看 | 狠狠躁夜夜躁人人爽超碰97香蕉 | 日韩国产在线观看 | 久久免费精品一区二区三区 | 欧美一区免费观看 | 成人中心免费视频 | 成人免费在线电影 | 五月婷婷丁香色 | 欧美在线视频一区二区 | 成人在线观看你懂的 | 色噜噜日韩精品一区二区三区视频 | 国产精品欧美精品 | 日韩乱理 | 992tv在线观看 | 国产精品一区免费观看 | 久久久久久福利 | 美女黄频 | 中文字幕日本在线 | 国产一级不卡毛片 | 久久精彩免费视频 | 黄色大片中国 | 97超碰资源站 | 色综合激情久久 | 国产精品久久久久9999 | 国产精品免费视频网站 | 日本在线视频网址 | 在线看国产日韩 | 色是在线视频 | 亚洲国产中文字幕 | 国产福利91精品一区二区三区 | wwwwww国产| 91xav| 日韩综合视频在线观看 | 狠狠色伊人亚洲综合网站野外 | 91爱看片 | 97视频免费在线看 | 日韩高清成人 | 国产手机在线观看 | 在线国产99 | 色综合久 | 精品欧美乱码久久久久久 | 狠狠色噜噜狠狠 | 国产98色在线 | 日韩 | 欧美精品久久久久久 | 在线a亚洲视频播放在线观看 | 探花视频免费观看 | 精品亚洲在线 | 四虎成人av | 一本—道久久a久久精品蜜桃 | 97色涩| 亚洲国产精品一区二区尤物区 | 久久精品视频网站 | 免费看91的网站 | 丁香婷婷激情国产高清秒播 | 亚洲激情久久 | 久久久久久久久毛片精品 | 欧美少妇xxxxxx | 在线影视 一区 二区 三区 | 天天干天天在线 | 五月婷婷六月丁香 | 成年人av在线播放 | 天天干,天天射,天天操,天天摸 | 国产99久久 | 九九热在线播放 | 国产免费不卡 | 日韩视频中文字幕在线观看 | www.com久久| 国产丝袜网站 | 最新不卡av | 久久av网 | 亚洲天天草 | 一区久久久 | 色婷婷在线观看视频 | 中文字幕一区二区三区视频 | 亚洲欧洲中文日韩久久av乱码 | 六月丁香激情网 | 欧美日产一区 | 久色网| 国产电影一区二区三区四区 | 久草免费资源 | 国产区高清在线 | 国产成人1区 | 亚洲色综合| 99热99re6国产在线播放 | 狠狠色噜噜狠狠狠 | 五月花丁香婷婷 | 成年人在线观看视频免费 | 色综合网在线 | 国产中年夫妇高潮精品视频 | 欧美精品亚洲二区 | 美女久久 | 亚洲做受高潮欧美裸体 | 亚洲一区精品人人爽人人躁 | 日韩美av在线 | 色综合久久久网 | 国产成人在线一区 | 久草在线在线精品观看 | 久久免费在线观看视频 | 亚洲dvd| 色多多视频在线 | 久久免费观看少妇a级毛片 久久久久成人免费 | 中文字幕在线观看第三页 | 狠狠色噜噜狠狠 | 免费激情在线电影 | 精品国产一区二区三区在线观看 | 国产91精品一区二区麻豆网站 | 日韩久久网站 | 成人一区不卡 | 亚洲伊人成综合网 | 国产黄色片免费 | 国产亚州精品视频 | 91刺激视频| 国产一区二区三区网站 | 亚洲欧洲一区二区在线观看 | 91手机视频 | 中文字幕在线观看视频一区 | 99超碰在线播放 | 日本最大色倩网站www | 成人国产精品入口 | 亚洲精品国产精品久久99热 | 亚洲国产精品成人va在线观看 | 国产精品自产拍在线观看网站 | 免费在线观看av网站 | 成人在线视频免费观看 | 91精品久久久久久综合乱菊 | 黄色的网站免费看 | 成人作爱视频 | 日韩免费一区二区 | 色视频成人在线观看免 | 婷婷综合影院 | 久久久久亚洲精品成人网小说 | 国产精品一区二区av麻豆 | 黄色在线免费观看网址 | 在线免费观看涩涩 | 免费国产在线精品 | 日本在线观看视频一区 | 免费看片网址 | 中文字幕永久免费 | 91视频高清免费 | 久久久久欠精品国产毛片国产毛生 | 欧美一二三四在线 | 超碰97在线资源站 | 欧美日韩一区二区免费在线观看 | 欧美专区国产专区 | 国模视频一区二区三区 | 日韩精品一区二区电影 | 亚洲成人精品影院 | 免费看黄色91 | 黄色毛片大全 | 欧美亚洲国产一卡 | 成av在线 | 免费国产在线精品 | 久久九九国产精品 | 91视频传媒 | 亚洲国产精品激情在线观看 | 99夜色| 麻豆成人精品视频 | 91久久在线观看 | 亚洲日本一区二区在线 | 婷婷丁香激情 | 狠狠色丁香婷婷综合橹88 | 激情文学丁香 | 欧美成年人在线观看 | 狠狠躁日日躁狂躁夜夜躁av | 国产精品久久久久久模特 | 国产视频亚洲视频 | 国产999精品久久久久久绿帽 | 日韩国产欧美在线播放 | 免费男女羞羞的视频网站中文字幕 | 在线看成人片 | 天天搞天天干 | 亚洲精品美女在线观看播放 | 欧美日韩伦理在线 | 婷婷久久亚洲 | 久久免费电影网 | 日韩在线观看不卡 | 亚洲理论在线 | 丁香花在线观看免费完整版视频 | 久久久国产一区二区三区四区小说 | 丁香六月婷婷综合 | 久久69av| 日韩精品一区二区久久 | 日韩欧美国产免费播放 | 伊人天天综合 | 激情综合网婷婷 | 成人av中文字幕在线观看 | 久久综合亚洲鲁鲁五月久久 | 在线精品视频免费观看 | 日韩精品免费在线观看视频 | 2021国产精品视频 | 久久成人免费电影 | 国产精品美女www爽爽爽视频 | 在线观看国产亚洲 | 在线看片一区 | 国产精品成人一区二区 | 国产91粉嫩白浆在线观看 | 天天综合网~永久入口 | 日本精品中文字幕 | 久久老司机精品视频 | 一级一级一片免费 | 日韩免费视频观看 | 97视频网站 | 婷婷激情影院 | 精品亚洲欧美一区 | 最新色站| 91av网站在线观看 | 精品毛片在线 | 国产美女视频 | 国产精品日韩久久久久 | 国产精品久久久区三区天天噜 | 亚洲一区二区三区毛片 | 9在线观看免费高清完整版在线观看明 | 免费av网站在线 | 天堂av在线7 | 日韩一区二区在线免费观看 | 91片黄在线观看动漫 | 国产超碰在线观看 | 精品色综合 | 国产亚洲精品v | 国产在线不卡精品 | 五月婷婷在线视频观看 | 成人a视频片观看免费 | 国产精品一区二 | 色婷婷福利 | 91香蕉视频在线 | 天天操狠狠操网站 | 日韩视频免费观看高清完整版在线 | 黄色a在线观看 | 日韩大片在线看 | 一区二区中文字幕在线播放 | 日韩黄色免费在线观看 | 中日韩男男gay无套 日韩精品一区二区三区高清免费 | 一区中文字幕电影 | 欧美色图狠狠干 | 成人影片在线播放 | 中文字幕国产一区二区 | 98超碰在线观看 | 午夜视频一区二区 | 午夜精品久久久久久久99无限制 | 二区中文字幕 | 日日天天av | 国产精品美女 | 国产免费一区二区三区最新6 | 视频一区久久 | 热久久免费国产视频 | 福利视频区 | 久久久久免费 | 中文字幕在线视频一区二区三区 | 丁香花在线视频观看免费 | 免费一级片观看 | 久久69精品 | 国产高清不卡在线 | 国产精品久久久久久久久久直播 | 又黄又爽的免费高潮视频 | 在线观看深夜福利 | 一区二区三区四区精品 | 国产色女人 | 四虎小视频 | 激情视频国产 | 日本精品视频网站 | 国产成人精品一区二区三区 | 91成人小视频 | 成人黄色免费在线观看 | jizz欧美性9| 国产高清不卡在线 | 玖玖玖国产精品 | 日韩理论在线 | 国产精品久久久999 国产91九色视频 | 国产69精品久久99的直播节目 | 国产99中文字幕 | 日韩高清一区在线 | 精品欧美在线视频 | 天天操导航 | 狠狠狠色丁香婷婷综合久久五月 | 色婷婷色 | 亚洲人成人在线 | 国产日本三级 | 欧美最猛性xxxxx亚洲精品 | 亚洲乱码在线 | 天天操天天干天天摸 | 日韩精品一区二区三区外面 | 91精品国产福利在线观看 | 日本在线中文 | 日韩欧美综合在线视频 | 成人久久精品视频 | 久久久久欠精品国产毛片国产毛生 | 日韩精品一区二区在线观看视频 | 亚洲乱码精品久久久久 | 久久黄色网页 | 久久再线视频 | 五月天精品视频 | 热久久精品在线 | 国产区免费在线 | 日本一区二区三区视频在线播放 | 国产人在线成免费视频 | 欧美一级免费片 | 99精品视频免费观看视频 | 激情欧美一区二区三区 | 91中文字幕永久在线 | 久久人人爽人人爽人人 | 国产玖玖在线 | 久久av福利| 99操视频 | 国产91学生粉嫩喷水 | 欧美一级大片在线观看 | 在线导航av | 国产精品videossex国产高清 | 东方av在线免费观看 | 久久久 精品 | 久久 一区 | 日日爽天天爽 | 国产精品v欧美精品v日韩 | 97操碰 | 国产精品久久久视频 | av电影在线观看完整版一区二区 | 欧美性色网站 | 免费在线播放黄色 | 天堂久久电影网 | 国产亚洲成人网 | 天堂成人在线 | 欧美视屏一区二区 | 欧美日韩网站 | 精品高清美女精品国产区 |