青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品

笑看風云淡

寵辱不驚,看庭前花開花落;去留無意,望天空云卷云舒
posts - 96, comments - 48, trackbacks - 0, articles - 0
  C++博客 :: 首頁 :: 新隨筆 ::  :: 聚合  :: 管理

Windows編程中的堆管理

Posted on 2010-01-21 11:52 天之驕子 閱讀(999) 評論(0)  編輯 收藏 引用
1 引言

  在大多數(shù)Windows應用程序設計中,都幾乎不可避免的要對內存進行操作和管理。在進行大尺寸內存的動態(tài)分配時尤其顯的重要。本文即主要對內存管理中的堆管理技術進行論述。

  堆(Heap)實際是位于保留的虛擬地址空間中的一個區(qū)域。剛開始時,保留區(qū)域中的多數(shù)頁面并沒有被提交物理存儲器。隨著從堆中越來越多的進行內存分配,堆管理器將逐漸把更多的物理存儲器提交給堆。堆的物理存儲器從系統(tǒng)頁文件中分配,在釋放時有專門的堆管理器負責對已占用物理存儲器的回收。堆管理也是Windows提供的一種內存管理機制。主要用來分配小的數(shù)據(jù)塊。與Windows的其他兩種內存管理機制虛擬內存和內存映射文件相比,堆可以不必考慮諸如系統(tǒng)的分配粒度和頁面邊界之類比較煩瑣而又容易忽視的問題,可將注意力集中于對程序功能代碼的設計上。但是使用堆去分配、釋放內存的速度要比其他兩種機制慢的多,而且不具備直接控制物理存儲器提交與回收的能力。

  在進程剛啟動時,系統(tǒng)便在剛創(chuàng)建的進程虛擬地址空間中創(chuàng)建了一個堆,該堆即為進程的默認堆,缺省大小為1MB,該值允許在鏈接程序時被更改。進程的默認堆是比較重要的,可供眾多Windows函數(shù)使用。在使用時,系統(tǒng)必須保證在規(guī)定的時間內,每此只有一個線程能夠分配和釋放默認堆中的內存塊。雖然這種限制將會對訪問速度產生一定的影響,但卻可以保證進程中的多個線程在同時調用各種Windows函數(shù)時對默認堆的順序訪問。在進程中允許使用多個堆,進程中包括默認堆在內的每個堆都有一個堆句柄來標識。與自己創(chuàng)建的堆不同,進程默認堆的創(chuàng)建、銷毀均由系統(tǒng)來完成,而且其生命期早在進程開始執(zhí)行之前就已經開始,雖然在程序中可以通過GetProcessHeap()函數(shù)得到進程的默認堆句柄,但卻不允許調用HeapDestroy()函數(shù)顯式將其撤消。

  2 對動態(tài)創(chuàng)建堆的需求

  前面曾提到,在進程中除了進程默認堆外,還可以在進程虛擬地址空間中動態(tài)創(chuàng)建一些獨立的堆。至于在程序設計時究竟需不需要動態(tài)創(chuàng)建獨立的堆可以從是否有保護組件的需要、是否能更加有效地對內存進行管理、是否有進行本地訪問的需要、是否有減少線程同步開銷的需要以及是否有迅速釋放堆的需要等幾個方面去考慮。

  對于是否有保護組件的需要這一原則比較容易理解。在圖1中,左邊的圖表示了一個鏈表(節(jié)點結構)組件和一個樹(分支結構)組件共同使用一個堆的情況。在這種情況下,由于兩組件數(shù)據(jù)在堆中的混合存放,如果節(jié)點3(屬于鏈表組件)的后幾個字節(jié)由于被錯誤改寫,將有可能影響到位于其后的分支2(屬于樹組件)。這將致使樹組件的相關代碼在遍歷其樹時由于內存被破壞而無法進行。究其原因,樹組件的內存是由于鏈表組建對其自身的錯誤操作而引起的。如果采用右圖所示方式,將樹組件和鏈表組件分別存放于一個獨立的堆中,上述情況顯然不會發(fā)生,錯誤將被局限于進行了錯誤操作的鏈表組件,而樹組件由于存放在獨立的堆中而受到了保護。


圖1 動態(tài)創(chuàng)建堆在保護組件中的作用

  在上圖中,如果鏈表組件的每個節(jié)點占用12個字節(jié),每個樹組件的分支占用16個字節(jié)如果這些長度不一的對象共用一個堆(左圖),在左圖中這些已經分配了內存的對象已占滿了堆,如果其中有節(jié)點2和節(jié)點4釋放,將會產生24個字節(jié)的碎片,如果試圖在24個字節(jié)的空閑區(qū)間內分配一個16字節(jié)的分支對象,盡管要分配的字節(jié)數(shù)小于空閑字節(jié)數(shù),但分配仍將失敗。只有在堆棧中分配大小相同的對象才可以實行更加有效的內存管理。如果將樹組件換成其他長度為12字節(jié)的組件,那么在釋放一個對象后,另一個對象就可以恰好填充到此剛釋放的對象空間中。

  進行本地訪問的需要也是一條比較重要的原則。系統(tǒng)會經常在內存與系統(tǒng)頁文件之間進行頁面交換,但如果交換次數(shù)過多,系統(tǒng)的運行性能就將受很大的影響。因此在程序設計時應盡量避免系統(tǒng)頻繁交換頁面,如果將那些會被同時訪問到的數(shù)據(jù)分配在相互靠近的位置上,將會減少系統(tǒng)在內存和頁文件之間的頁面交換頻率。

  線程同步開銷指的是默認條件下以順序方式運行的堆為保護數(shù)據(jù)在多個線程試圖同時訪問時不受破壞而必須執(zhí)行額外代碼所花費的開銷。這種開銷保證了堆對線程的安全性,因此是有必要的,但對于大量的堆分配操作,這種額外的開銷將成為一個負擔,并降低程序的運行性能。為避免這種額外的開銷,可以在創(chuàng)建新堆時通知系統(tǒng)只有單個線程對訪問。此時堆對線程的安全性將有應用程序來負責。

  最后如果有迅速釋放堆的需要,可將專用堆用于某些數(shù)據(jù)結構,并以整個堆去釋放,而不再顯式地釋放在堆中分配的每一個內存塊。對于大多數(shù)應用程序,這樣的處理將能以更快的速度運行。
3 創(chuàng)建堆

  在進程中,如果需要可以在原有默認堆的基礎上動態(tài)創(chuàng)建一個堆,可由HeapCreate()函數(shù)完成:

HANDLE HeapCreate(
 DWORD flOptions,
 DWORD dwInitialSize,
 DWORD dwMaximumSize
);

  其第一個參數(shù)flOptions指定了對新建堆的操作屬性。該標志將會影響一些堆函數(shù)如HeapAlloc()、HeapFree()、HeapReAlloc()和HeapSize()等對新建堆的訪問。其可能的取值為下列標志及其組合:

屬性標志 說明
HEAP_GENERATE_EXCEPTIONS 在遇到由于內存越界等而引起的函數(shù)失敗時,由系統(tǒng)拋出一個異常來指出此失敗,而不是簡單的返回NULL指針。
HEAP_NO_SERIALIZE 指明互斥現(xiàn)象不會出現(xiàn)

  參數(shù)dwInitialSize和dwMaximumSize分別為堆的初始大小和堆棧的最大尺寸。其中,dwInitialSize的值決定了最初提交給堆的字節(jié)數(shù)。如果設置的數(shù)值不是頁面大小的整數(shù)倍,則將被圓整到鄰近的頁邊界處。而dwMaximumSize則實際上是系統(tǒng)能為堆保留的地址空間區(qū)域的最大字節(jié)數(shù)。如果該值為0,那么將創(chuàng)建一個可擴展的堆,堆的大小僅受可用內存的限制。如果應用程序需要分配大的內存塊,通常要將該參數(shù)設置為0。如果dwMaximumSize大于0,則該值限定了堆所能創(chuàng)建的最大值,HeapCreate()同樣也要將該值圓整到鄰近的頁邊界,然后再在進程的虛擬地址空間為堆保留該大小的一塊區(qū)域。在這種堆中分配的內存塊大小不能超過0x7FFF8字節(jié),任何試圖分配更大內存塊的行為將會失敗,即使是設置的堆大小足以容納該內存塊。如果HeapCreate()成功執(zhí)行,將會返回一個標識新堆的句柄,并可供其他堆函數(shù)使用。

  需要特別說明的是,在設置第一個參數(shù)時,對HEAP_NO_SERIALIZE的標志的使用要謹慎,一般應避免使用該標志。這是同后續(xù)將要進行的堆函數(shù)HeapAlloc()的執(zhí)行過程有關系的,在HeapAlloc()試圖從堆中分配一個內存塊時,將執(zhí)行下述幾步操作:

  1) 遍歷分配的和釋放的內存塊的鏈接表

  2) 搜尋一個空閑內存塊的地址

  3) 通過將空閑內存塊標記為"已分配"來分配新內存塊

  4) 將新分配的內存塊添加到內存塊列表

  如果這時有兩個線程1、2試圖同時從一個堆中分配內存塊,那么線程1在執(zhí)行了上面的1和2步后將得到空間內存塊的地址。但是由于CPU對線程運行時間的分片,使得線程1在執(zhí)行第3步操作前有可能被線程2搶走執(zhí)行權并有機會去執(zhí)行同樣的1、2步操作,而且由于先執(zhí)行的線程1并沒有執(zhí)行到第3步,因此線程2會搜尋到同一個空閑內存塊的地址,并將其標記為已分配。而線程1在恢復運行后并不能知曉該內存塊已被線程2標記過,因此會出現(xiàn)兩個線程軍認為其分配的是空閑的內存塊,并更新各自的聯(lián)接表。顯然,象這種兩個線程擁有完全相同內存塊地址的錯誤是非常嚴重而又是難以發(fā)現(xiàn)的。

  由于只有在多個線程同時進行操作時才有可能出現(xiàn)上述問題,一種簡單的解決的辦法就是不使用HEAP_NO_SERIALIZE標志而只允許單個線程獨占地對堆及其聯(lián)接表擁有訪問權。如果一定要使用此標志,為了安全起見,必須確保進程為單線程的或是在進程中使用了多線程,但只有單個線程對堆進行訪問。再就是使用了多線程,也有多個線程對堆進行了訪問,但這些線程通過使用某種線程同步手段。如果可以確保以上幾條中的一條成立,也是可以安全使用HEAP_NO_SERIALIZE標志的,而且還將擁有快的訪問速度。如果不能肯定上述條件是否滿足,建議不使用此標志而以順序的方式訪問堆,雖然線程速度會因此而下降但卻可以確保堆及其中數(shù)據(jù)的不被破壞。

  4 從堆中分配內存塊

  在成功創(chuàng)建一個堆后,可以調用HeapAlloc()函數(shù)從堆中分配內存塊。在此,除了可以從用HeapCreate()創(chuàng)建的動態(tài)堆中分配內存塊,也可以直接從進程的默認堆中分配內存塊。下面先給出HeapCreate()的函數(shù)原型:

LPVOID HeapAlloc(
 HANDLE hHeap,
 DWORD dwFlags,
 DWORD dwBytes
);

  其中,參數(shù)hHeap為要分配的內存塊來自的堆的句柄,可以是從HeapCreate()創(chuàng)建的動態(tài)堆句柄也可以是由GetProcessHeap()得到的默認堆句柄。參數(shù)dwFlags指定了影響堆分配的各個標志。該標志將覆蓋在調用HeapCreate()時所指定的相應標志,可能的取值為:

標志 說明
HEAP_GENERATE_EXCEPTIONS 該標志指定在進行諸如內存越界操作等情況時將拋出一個異常而不是簡單的返回NULL指針
HEAP_NO_SERIALIZE 強制對HeapAlloc()的調用將與訪問同一個堆的其他線程不按照順序進行
HEAP_ZERO_MEMORY 如果使用了該標志,新分配內存的內容將被初始化為0

  最后一個參數(shù)dwBytes設定了要從堆中分配的內存塊的大小。如果HeapAlloc()執(zhí)行成功,將會返回從堆中分配的內存塊的地址。如果由于內存不足或是其他一些原因而引起HeapAlloc()函數(shù)的執(zhí)行失敗,將會引發(fā)異常。通過異常標志可以得到引起內存分配失敗的原因:如果為STATUS_NO_MEMORY則表明是由于內存不足引起的;如果是STATUS_ACCESS_VIOLATION則表示是由于堆被破壞或函數(shù)參數(shù)不正確而引起分配內存塊的嘗試失敗。以上異常只有在指定了HEAP_GENERATE_EXCEPTIONS標志時才會發(fā)生,如果沒有指定此標志,在出現(xiàn)類似錯誤時HeapAlloc()函數(shù)只是簡單的返回NULL指針。

  在設置dwFlags參數(shù)時,如果先前用HeapCreate()創(chuàng)建堆時曾指定過HEAP_GENERATE_EXCEPTIONS標志,就不必再去設置HEAP_GENERATE_EXCEPTIONS標志了,因為HEAP_GENERATE_EXCEPTIONS標志已經通知堆在不能分配內存塊時將會引發(fā)異常。另外,對HEAP_NO_SERIALIZE標志的設置應慎重,與在HeapCreate()函數(shù)中使用HEAP_NO_SERIALIZE標志類似,如果在同一時間有其他線程使用同一個堆,那么該堆將會被破壞。如果是在進程默認堆中進行內存塊的分配則要絕對禁用此標志。

  在使用堆函數(shù)HeapAlloc()時要注意:堆在內存管理中的使用主要是用來分配一些較小的數(shù)據(jù)塊,如果要分配的內存塊在1MB左右,那么就不要再使用堆來管理內存了,而應選擇虛擬內存的內存管理機制。
5 再分配內存塊

  在程序設計時經常會由于開始時預見不足而造成在堆中分配的內存塊大小的不合適(多數(shù)情況是開始時分配的內存較小,而后來實際需要更多的數(shù)據(jù)復制到內存塊中去)這就需要在分配了內存塊后再根據(jù)需要調整其大小。堆函數(shù)HeapReAlloc()將完成這一功能,其函數(shù)原型為:

LPVOID HeapReAlloc(
 HANDLE hHeap,
 DWORD dwFlags,
 LPVOID lpMem,
 DWORD dwBytes
);

  其中,參數(shù)hHeap為包含要調整其大小的內存塊的堆的句柄。dwFlags參數(shù)指定了在更改內存塊大小時HeapReAlloc()函數(shù)所使用的標志。其可能的取值為HEAP_GENERATE_EXCEPTIONS、HEAP_NO_SERIALIZE、HEAP_REALLOC_IN_PLACE_ONLY和HEAP_ZERO_MEMORY,其中前兩個標志的作用與在HeapAlloc()中的作用相同。HEAP_REALLOC_IN_PLACE_ONLY標志在內存塊被加大時不移動堆中的內存塊,在沒有設置此標志的情況下如果對內存進行增大,那么HeapReAlloc()函數(shù)將有可能將原內存塊移動到一個新的地址。顯然,在設置了該標志禁止內存快首地址進行調整時,將有可能出現(xiàn)沒有足夠的內存供試圖增大的內存塊使用,對于這種情況,函數(shù)對內存塊增大調整的操作是失敗的,內存塊將仍保留原有的大小和位置。HEAP_ZERO_MEMORY標志的用處則略有不同,如果內存快經過調整比以前大,那么新增加的那部分內存將被初始化為0;如果經過調整內存塊縮小了,那么該標志將不起任何作用。

  函數(shù)的最后兩個參數(shù)lpMem和dwBytes分別為指向再分配內存塊的指針和再分配的字節(jié)數(shù)。如果函數(shù)成功執(zhí)行,將返回新的改變了大小的內存塊的地址。如果在調用時使用了HEAP_REALLOC_IN_PLACE_ONLY標志,那么返回的地址將與原內存塊地址相同。如果因為內存不足等原因而引起函數(shù)的執(zhí)行失敗,函數(shù)將返回一個NULL指針。但是HeapReAlloc()的執(zhí)行失敗并不會影響原內存塊,它將保持原來的大小和位置繼續(xù)存在。可以通過HeapSize()函數(shù)來檢索內存塊的實際大小。

  6 釋放堆內存、撤消堆

  在不再需要使用堆中的內存塊時,可以通過HeapFree()將其予以釋放。該函數(shù)結構比較簡單,只含有三個參數(shù):

BOOL HeapFree(
 HANDLE hHeap,
 DWORD dwFlags,
 LPVOID lpMem
);

  其中,hHeap為要包含要釋放內存塊的堆的句柄;參數(shù)dwFlags為堆棧的釋放選項可以是0,也可以是HEAP_NO_SERIALIZE;最后的參數(shù)lpMem為指向內存塊的指針。如果函數(shù)成功執(zhí)行,將釋放指定的內存塊,并返回TRUE。該函數(shù)的主要作用是可以用來幫助堆管理器回收某些不使用的物理存儲器以騰出更多的空閑空間,但是并不能保證一定會成功。

  最后,在程序退出前或是應用程序不再需要其創(chuàng)建的堆了,可以調用HeapDestory()函數(shù)將其銷毀。該函數(shù)只包含一個參數(shù)--待銷毀的堆的句柄。HeapDestory()的成功執(zhí)行將可以釋放堆中包含的所有內存塊,也可將堆占用的物理存儲器和保留的地址空間區(qū)域全部重新返回給系統(tǒng)并返回TRUE。該函數(shù)只對由HeapCreate()顯式創(chuàng)建的堆起作用,而不能銷毀進程的默認堆,如果強行將由GetProcessHeap()得到的默認堆的句柄作為參數(shù)去調用HeapDestory(),系統(tǒng)將會忽略對該函數(shù)的調用。
7 對new與delete操作符的重載

  new與delete內存空間動態(tài)分配操作符是C++中使用堆進行內存管理的一種常用方式,在程序運行過程中可以根據(jù)需要隨時通過這兩個操作符建立或刪除堆對象。new操作符將在堆中分配一個足夠大小的內存塊以存放指定類型的對象,如果每次構造的對象類型不同,則需要按最大對象所占用的空間來進行分配。new操作符在成功執(zhí)行后將返回一個類型與new所分配對象相匹配的指針,如果不匹配則要對其進行強制類型轉換,否則將會編譯出錯。在不再需要這個對象的時候,必須顯式調用delete操作符來釋放此空間。這一點是非常重要的,如果在預分配的緩沖里構造另一個對象之前或者在釋放緩沖之前沒有顯式調用delete操作符,那么程序將產生不可預料的后果。在使用delete操作符時,應注意以下幾點:

  1) 它必須使用于由運算符new返回的指針

  2) 該操作符也適用于NULL指針

  3) 指針名前只用一對方括號符,并且不管所刪除數(shù)組的維數(shù),忽略方括號內的任何數(shù)字

class CVMShow{
 private:
  static HANDLE m_sHeap;
  static int m_sAllocedInHeap;
 public:
  LPVOID operator new(size_t size);
  void operator delete(LPVOID pVoid);
}

……
HANDLE m_sHeap = NULL;
int m_sAllocedInHeap = 0;
LPVOID CVMShow::operator new(size_t size)
{
 if (m_sHeap == NULL)
  m_sHeap = HeapCreate(HEAP_GENERATE_EXCEPTIONS, 0, 0);
  LPVOID pVoid = HeapAlloc(m_sHeap, 0, size);
  if (pVoid == NULL)
   return NULL;
   m_sAllocedInHeap++;
  return pVoid;
}
void CVMShow::operator delete(LPVOID pVoid)
{
 if (HeapFree(m_sHeap, 0, pVoid))
  m_sAllocedInHeap--;
  if (m_sAllocedInHeap == 0)
  {
   if (HeapDestory(m_sHeap))
    m_sHeap = NULL;
  }
}

  在程序中除了直接用上述方法使用new和delete來建立和刪除堆對象外,還可以通過為C++類重載new和delete操作符來方便地利用堆棧函數(shù)。上面的代碼對它們進行了簡單的重載,并通過靜態(tài)變量m_sHeap和m_sAllocedInHeap在類CVMShow的所有實例間共享唯一的堆句柄(因為在這里CVMShow類的所有實例都是在同一個堆中進行內存分配的)和已分配類對象的計數(shù)。這兩個靜態(tài)變量在代碼開始執(zhí)行時被分別初始化為NULL指針和0計數(shù)。

  重載的new操作符在第一次被調用時,由于靜態(tài)變量m_sHeap為NULL標志著堆尚未創(chuàng)建,就通過HeapCreate()函數(shù)創(chuàng)建一個堆并返回堆句柄到m_sHeap。隨后根據(jù)入口參數(shù)size所指定的大小在堆中分配內存,同時已分配內存塊計數(shù)器m_sAllocedInHeap累加。在該操作符的以后調用過程中,由于堆已經創(chuàng)建,故不再創(chuàng)建堆,而是直接在堆中分配指定大小的內存塊并對已分配的內存塊個數(shù)進行計數(shù)。

  在CVMShow類對象不再被應用程序所使用時,需要將其撤消,由重載的delete操作符完成此工作。delete操作符只接受一個LPVOID型參數(shù),即被刪除對象的地址。該函數(shù)在執(zhí)行時首先調用HeapFree()函數(shù)將指定的已分配內存的對象釋放并對已分配內存計數(shù)遞減1。如果該計數(shù)不為零則表明當前堆中的內存塊沒有全部釋放,堆暫時不予撤消。如果m_sAllocedInHeap計數(shù)減到0,則堆中已釋放完所有的CVMShow對象,可以調用HeapDestory()函數(shù)將堆銷毀,并將堆句柄m_sHeap設置為NULL指針。這里在撤消堆后將堆句柄設置為NULL指針的操作是完全必要的。如果不執(zhí)行該操作,當程序再次調用new操作符去分配一個CVMShow類對象時將會認為堆是存在的而會試圖在已撤消的堆中去分配內存,顯然將會導致失敗。

  象CVMShow這樣設計的類通過對new和delete操作符的重載,并且在一個堆中為所有的CVMShow類對象進行分配,可以節(jié)省在為每一個類都創(chuàng)建堆的分配開銷與內存。這樣的處理還可以讓每一個類都擁有屬于自己的堆,并且允許派生類對其共享,這在程序設計中也是比較好的一種處理方法。

  8 小結

  在使用堆時有時會造成系統(tǒng)運行速度的減慢,通常是由以下原因造成的:分配操作造成的速度減慢;釋放操作造成的速度減慢;堆競爭造成的速度減慢;堆破壞造成的速度減慢;頻繁的分配和重分配造成的速度減慢等。其中,競爭是在分配和釋放操作中導致速度減慢的問題。基于上述原因,建議不要在程序中過于頻繁的使用堆。

只有注冊用戶登錄后才能發(fā)表評論。
網站導航: 博客園   IT新聞   BlogJava   博問   Chat2DB   管理


青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <ins id="pjuwb"></ins>
    <blockquote id="pjuwb"><pre id="pjuwb"></pre></blockquote>
    <noscript id="pjuwb"></noscript>
          <sup id="pjuwb"><pre id="pjuwb"></pre></sup>
            <dd id="pjuwb"></dd>
            <abbr id="pjuwb"></abbr>
            亚洲成色777777在线观看影院| 亚洲电影在线观看| 亚洲欧美制服另类日韩| 免费欧美日韩国产三级电影| 亚洲欧美日韩在线播放| 欧美日韩免费在线视频| 99re热这里只有精品免费视频| 久久这里只精品最新地址| 日韩一二三在线视频播| 亚洲欧美日韩国产中文在线| 欧美激情精品久久久久久大尺度 | 美女视频黄 久久| 亚洲性图久久| 夜夜嗨av一区二区三区中文字幕 | 亚洲日韩欧美视频一区| 欧美午夜视频在线观看| 这里只有精品电影| 亚洲一区亚洲| 亚洲片国产一区一级在线观看| 久久看片网站| 亚洲国产天堂久久国产91| 欧美aⅴ一区二区三区视频| 久久久久国产免费免费| 亚洲国产成人一区| 欧美激情第三页| 欧美激情二区三区| 国产精品99久久久久久久久久久久 | 欧美女同在线视频| 亚洲少妇诱惑| 亚洲欧美亚洲| 国产精品影院在线观看| 性欧美办公室18xxxxhd| 亚洲一二三区在线| 国产精品久久久久久久久久久久久久| 91久久国产精品91久久性色| 欧美激情第一页xxx| 欧美日韩另类在线| 午夜欧美精品久久久久久久| 欧美一二三区精品| 一区视频在线播放| 亚洲精品美女91| 国产九区一区在线| 欧美激情中文字幕在线| 国产精品福利在线| 久久视频这里只有精品| 欧美成人在线网站| 欧美一区二区三区在线观看| 免费不卡在线观看| 欧美一区二区三区婷婷月色 | 性欧美激情精品| 欧美一二三区精品| 亚洲免费播放| 欧美伊人影院| 99riav1国产精品视频| 午夜在线不卡| 99精品视频免费观看| 欧美在线免费看| 亚洲综合电影一区二区三区| 在线观看一区二区视频| 中日韩在线视频| 亚洲国产专区校园欧美| 亚久久调教视频| 亚洲欧美国产毛片在线| 欧美韩日一区二区| 久久综合激情| 国产一区二区三区成人欧美日韩在线观看 | 亚洲激情在线观看| 亚洲欧洲精品一区二区三区波多野1战4 | 亚洲国产日韩欧美在线动漫| 性8sex亚洲区入口| 亚洲一区二区毛片| 欧美gay视频激情| 久久久久亚洲综合| 国产日韩一区二区三区在线播放| 亚洲乱码视频| 亚洲精品视频免费观看| 老司机免费视频一区二区| 久久精品欧美日韩| 国产酒店精品激情| 亚洲综合视频网| 午夜欧美精品久久久久久久| 国产精品乱码人人做人人爱| 一本色道久久综合亚洲精品不卡| 一本色道久久综合一区| 欧美精品一区三区在线观看| 欧美高清成人| 91久久精品一区二区三区| 美女福利精品视频| 亚洲高清在线播放| 亚洲精品系列| 欧美日韩激情网| 一区二区三区日韩| 亚洲欧洲av一区二区| 国产欧美日韩在线播放| 欧美在线一二三| 久久午夜激情| 亚洲国产欧美一区| 欧美激情综合色综合啪啪| 亚洲精品中文字幕女同| 亚洲在线日韩| 国产日韩精品综合网站| 久久精品视频免费播放| 欧美电影免费观看高清完整版| 亚洲人成网站777色婷婷| 欧美激情亚洲| 亚洲永久免费av| 久久综合一区| 99re8这里有精品热视频免费| 欧美三级网页| 久久精品国产久精国产爱| 欧美激情免费观看| 亚洲私人影吧| 国产视频在线观看一区二区| 巨胸喷奶水www久久久免费动漫| 亚洲大胆女人| 亚洲男人的天堂在线aⅴ视频| 国产亚洲精品高潮| 欧美大片一区二区| 亚洲一区精品在线| 牛人盗摄一区二区三区视频| 一区二区日韩精品| 国产一区二区三区日韩| 欧美—级a级欧美特级ar全黄| 亚洲嫩草精品久久| 亚洲国产成人不卡| 欧美在线精品免播放器视频| 亚洲欧洲精品一区| 国产亚洲观看| 欧美日韩一二三区| 久久免费视频在线观看| 亚洲视频欧美在线| 欧美国产高清| 欧美在线播放| 一本久道久久综合狠狠爱| 亚洲精品日韩综合观看成人91| 欧美影片第一页| 亚洲激情成人网| 久久精品男女| 亚洲视频一区在线| 又紧又大又爽精品一区二区| 欧美视频在线观看免费| 久久这里只精品最新地址| 亚洲天堂av在线免费| 欧美国产日韩在线观看| 久久精品亚洲一区| 亚洲永久免费精品| 99国产麻豆精品| 亚洲国产日韩欧美| 激情欧美日韩| 国产一区二区三区成人欧美日韩在线观看 | 久久久999成人| 亚洲五月婷婷| aa日韩免费精品视频一| 亚洲高清视频一区| 免费在线亚洲欧美| 久久久免费av| 欧美在线视频在线播放完整版免费观看| 亚洲三级电影全部在线观看高清| 国产一区二区三区视频在线观看| 国产精品久久久久永久免费观看| 欧美精品日韩一区| 欧美wwwwww| 免费欧美电影| 欧美~级网站不卡| 久久精品国产久精国产一老狼| 香蕉久久夜色精品国产| 亚洲欧美日韩国产综合在线| 中文国产一区| 一区二区三区不卡视频在线观看 | 校园春色综合网| 亚洲专区免费| 亚洲欧美日韩视频二区| 亚洲欧美日本日韩| 香蕉久久夜色| 久久久不卡网国产精品一区| 久久久999精品视频| 久久综合国产精品| 女生裸体视频一区二区三区| 欧美激情a∨在线视频播放| 亚洲电影免费在线| 亚洲精选久久| 一本大道久久精品懂色aⅴ| av成人免费观看| 亚洲一区二区三区免费在线观看| 亚洲性感美女99在线| 亚洲女同在线| 久久久www| 欧美激情网站在线观看| 欧美午夜a级限制福利片| 国产精品久久久久久久电影 | 亚洲欧美一区二区三区久久| 午夜电影亚洲| 老司机午夜精品视频| 亚洲第一天堂av| 日韩一级在线观看| 午夜精品久久久久久久久久久久久 | 中文在线一区| av成人毛片| 永久域名在线精品| 欧美精品一区二区三区视频|