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

C++ Programmer's Cookbook

{C++ 基礎} {C++ 高級} {C#界面,C++核心算法} {設計模式} {C#基礎}

.Net內存管理和垃圾回收

.NET 框架的垃圾回收器管理應用程序的內存分配和釋放。每次您使用 new 運算符創建對象時,運行庫都從托管堆為該對象分配內存。只要托管堆中有地址空間可用,運行庫就會繼續為新對象分配空間。但是,內存不是無限大的。最終,垃圾回收器必須執行回收以釋放一些內存。垃圾回收器優化引擎根據正在進行的分配情況確定執行回收的最佳時間。當垃圾回收器執行回收時,它檢查托管堆中不再被應用程序使用的對象并執行必要的操作來回收它們占用的內存。

開發人員在內存管理方面的背景
根據您開發背景的不同,您在內存管理方面的經驗也會有所不同。在某些情況下,您可能需要讓您的編程習慣來適應公共語言運行庫提供的自動內存管理。

COM 開發人員
COM 開發人員習慣于將實現引用計數作為一個手動的內存管理技術。每次引用一個對象,計數器就遞增。如果對對象的引用超出了范圍,計數器就遞減。當對象的引用計數達到零時,對象被終止并釋放其內存。

引用計數方案會引發許多調試錯誤。如果未能嚴格地按照引用計數的規則進行操作,對象可能被過早釋放或者未引用的對象積存在內存中。循環引用也是常見的問題根源。循環引用出現在子對象引用父對象,而父對象又引用子對象時。這種情況使兩個對象都不能被釋放或銷毀。唯一的解決方案就是讓父對象和子對象都遵守一個固定的使用和銷毀模式,例如總是先由父對象刪除子對象。

當使用托管語言開發應用程序時,運行庫的垃圾回收器免除了對引用進行計數的需要,因此也就避免了由這種手動管理內存方案引發的錯誤。

C++ 開發人員
C++ 開發人員熟悉與手動內存管理相關的任務。在 C++ 中,當您使用 new 運算符為對象分配內存時,您必須使用 delete 運算符釋放對象的內存。這可能導致多種錯誤,例如忘記釋放對象、引起內存泄漏或試圖訪問已被釋放的對象的內存。

當使用 C++ 的托管擴展或其他托管語言開發應用程序時,您就不必使用 delete 運算符釋放對象了。垃圾回收器在當對象不再被應用程序使用時自動為您完成這些操作。

考慮到手動管理短期對象內存的相關成本,C++ 開發人員可能習慣于避免使用這些對象。對于兩次回收間創建的然后又不再使用的托管短期對象,分配和釋放內存的成本非常低。在 .NET 框架中,實際上已經對垃圾回收器進行了優化來管理具有較短生存期的對象。當開發托管應用程序時,在短期對象可以簡化代碼的情況下使用它們是非常合適的。

Visual Basic 開發人員
Visual Basic 開發人員習慣于自動內存管理。您熟悉的編程慣例將應用于您在 .NET 框架中創建的大多數托管對象。但是,當創建或使用封裝非托管資源的對象時,您應該特別注意使用 Dispose 方法的推薦設計模式。

.NET 框架支持的托管語言比此處介紹的還要多。不管您使用哪一種托管語言,.NET 框架的垃圾回收器都提供自動內存管理。它為托管對象分配和釋放內存,并在必要時執行 Finalize 方法和析構函數來適當地清理非托管資源。自動內存管理通過消除手動內存管理方案引起的常見問題簡化了開發。

Finalize 方法和析構函數
對于您的應用程序創建的大多數對象,可以依靠 .NET 框架的垃圾回收器隱式地執行所有必要的內存管理任務。但是,在您創建封裝非托管資源的對象時,當您在應用程序中使用完這些非托管資源之后,您必須顯式地釋放它們。最常見的一類非托管資源就是包裝操作系統資源的對象,例如文件、窗口或網絡連接。雖然垃圾回收器可以跟蹤封裝非托管資源的對象的生存期,但它不了解具體如何清理這些資源。對于這些類型的對象,.NET 框架提供 Object.Finalize 方法,它允許對象在垃圾回收器回收該對象使用的內存適當清理其非托管資源默認情況下,Finalize 方法不執行任何操作。如果您要讓垃圾回收器在回收對象的內存之前對對象執行清理操作,您必須在類中重寫 Finalize 方法。當使用 C# 和 C++ 的托管擴展以外的編程語言進行開發時,您可以實現 Finalize 方法。C# 和托管擴展提供析構函數作為編寫終止代碼的簡化機制。析構函數自動生成 Finalize 方法和對基類的 Finalize 方法的調用。在 C# 和托管擴展編程語言中,您必須為終止代碼使用析構函數語法。

垃圾回收器使用名為“終止隊列”的內部結構跟蹤具有 Finalize 方法的對象。每次您的應用程序創建具有 Finalize 方法的對象時,垃圾回收器都在終止隊列中放置一個指向該對象的項。托管堆中所有需要在垃圾回收器回收其內存之前調用它們的終止代碼的對象都在終止隊列中含有項。

實現 Finalize 方法或析構函數對性能可能會有負面影響,因此應避免不必要地使用它們。用 Finalize 方法回收對象使用的內存需要至少兩次垃圾回收。當垃圾回收器執行回收時,它只回收沒有終結器的不可訪問對象的內存。這時,它不能回收具有終結器的不可訪問對象。它改為將這些對象的項從終止隊列中移除并將它們放置在標為準備終止的對象列表中。該列表中的項指向托管堆中準備被調用其終止代碼的對象。一個特殊的運行庫線程開始處于活動狀態并調用列表中對象的 Finalize 方法,然后將這些項從列表中移除。后來的垃圾回收將確定終止的對象確實是垃圾,因為標為準備終止對象的列表中的項不再指向它們。在后來的垃圾回收中,實際上回收了對象的內存。

清理非托管資源
通過將對象的范圍限制為 protected,您可以防止應用程序的用戶直接調用對象的 Finalize 方法。除此之外,我們強烈建議您不要直接從應用程序代碼中調用非基類的類的 Finalize 方法為適當處置非托管資源,建議您實現公共的 Dispose 或 Close 方法,這兩個方法執行必要的對象清理代碼。IDisposable 接口為實現接口的資源類提供 Dispose method。因為 Dispose 方法是公共的,所以應用程序的用戶可以直接調用該方法來釋放非托管資源占用的內存。如果正確實現了 Dispose 方法,則 Finalize 方法(或者 C# 中的析構函數或 C++ 的托管擴展)就成為避免在沒有調用 Dispose 方法的情況下清理資源的一種防護措施。

實現 Dispose 方法 [C#]
類型的 Dispose 方法應該釋放它擁有的所有資源。它還應該通過調用其父類型的 Dispose 方法釋放其基類型擁有的所有資源。該父類型的 Dispose 方法應該釋放它擁有的所有資源并同樣也調用其父類型的 Dispose 方法,從而在整個基類型層次結構中傳播該模式。要確保始終正確地清理資源,Dispose 方法應該可以被多次安全調用而不引發任何異常。

Dispose 方法應該為它處置的對象調用 GC.SuppressFinalize 方法。如果對象當前在終止隊列中,GC.SuppressFinalize 防止其 Finalize 方法被調用。請記住,執行 Finalize 方法會大大減損性能。如果您的 Dispose 方法已經完成了清理對象的工作,那么垃圾回收器就不必調用對象的 Finalize 方法了。

下面的代碼示例旨在闡釋如何為封裝了非托管資源的類實現 Dispose 方法的一種可能的設計模式。因為該模式是在整個 .NET 框架中實現的,所以您可能會發現它十分便于使用。但是,這不是 Dispose 方法唯一可能的實現。

資源類通常是從復雜的本機類或 API 派生的,而且必須進行相應的自定義。使用這一代碼模式作為創建資源類的一個起始點,并根據封裝的資源提供必要的自定義。不能編譯該示例,也不能將其直接用于應用程序。

在此示例中,基類 BaseResource 實現可由類的用戶調用的公共 Dispose 方法。而該方法又調用 virtual Dispose(bool disposing) 方法(Visual Basic 中的虛 Dispose(作為布爾值處置))。根據調用方的標識傳遞 true 或 false。以虛 Dispose 方法為對象執行適當的清理代碼。

Dispose(bool disposing) 以兩種截然不同的方案執行。如果處置結果為 true,則該方法已由用戶的代碼直接調用或間接調用,并且可處置托管資源和非托管資源。如果處置結果為 false,則該方法已由運行庫從終結器內部調用,并且只能處置非托管資源。因為終結器不會以任意特定的順序執行,所以當對象正在執行其終止代碼時,不應引用其他對象。如果正在執行的終結器引用了另一個已經終止的對象,則該正在執行的終結器將失敗。

基類提供的 Finalize 方法或析構函數在未能調用 Dispose 的情況下充當防護措施。Finalize 方法調用帶有參數的 Dispose 方法,同時傳遞 false。不應在 Finalize 方法內重新創建 Dispose 清理代碼。調用 Dispose(false) 可以優化代碼的可讀性和可維護性。

類 MyResourceWrapper 闡釋如何用 Dispose 從實現資源管理的類派生。MyResourceWrapper 重寫 virtual Dispose(bool disposing) 方法并為其創建的托管和非托管資源提供清理代碼。MyResourceWrapper 還對其基類 BaseResource 調用 Dispose 以確保其基類能夠適當地進行清理。請注意,派生類 MyResourceWrapper 沒有不帶參數的 Finalize 方法或 Dispose 方法,因為這兩個方法從基類 BaseResource 繼承它們。

[C#]?
// ?Design?pattern?for?the?base?class.?
// ?By?implementing?IDisposable,?you?are?announcing?that?instances?
// ?of?this?type?allocate?scarce?resources.?
public ? class ?BaseResource:?IDisposable?
{?
// ?Pointer?to?an?external?unmanaged?resource.?
private ?IntPtr?handle;?
// ?Other?managed?resource?this?class?uses.?
private ?Component?Components;?
// ?Track?whether?Dispose?has?been?called.?
private ? bool ?disposed? = ? false ;?

// ?Constructor?for?the?BaseResource?Object.?
public ?BaseResource()?
{?
// ?Insert?appropriate?constructor?code?here.?
}
?

// ?Implement?Idisposable.?
// ?Do?not?make?this?method?virtual.?
// ?A?derived?class?should?not?be?able?to?override?this?method.?
public ? void ?Dispose()?
{?
Dispose(
true );?
// ?Take?yourself?off?of?the?Finalization?queue?
// ?to?prevent?finalization?code?for?this?object?
// ?from?executing?a?second?time.?
GC.SuppressFinalize( this );?
}
?

// ?Dispose(bool?disposing)?executes?in?two?distinct?scenarios.?
// ?If?disposing?equals?true,?the?method?has?been?called?directly?
// ?or?indirectly?by?a?user's?code.?Managed?and?unmanaged?resources?
// ?can?be?disposed.?
// ?If?disposing?equals?false,?the?method?has?been?called?by?the?
// ?runtime?from?inside?the?finalizer?and?you?should?not?reference?
// ?other?objects.?Only?unmanaged?resources?can?be?disposed.?
protected ? virtual ? void ?Dispose( bool ?disposing)?
{?
// ?Check?to?see?if?Dispose?has?already?been?called.?
if ( ! this .disposed)?
{?
// ?If?disposing?equals?true,?dispose?all?managed?
// ?and?unmanaged?resources.?
if (disposing)?
{?
// ?Dispose?managed?resources.?
Components.Dispose();?
}
?
// ?Release?unmanaged?resources.?If?disposing?is?false,?
// ?only?the?following?code?is?executed.?
CloseHandle(handle);?
handle?
= ?IntPtr.Zero;?
// ?Note?that?this?is?not?thread?safe.?
// ?Another?thread?could?start?disposing?the?object?
// ?after?the?managed?resources?are?disposed,?
// ?but?before?the?disposed?flag?is?set?to?true.?
}
?
disposed?
= ? true ;?
}
?

// ?Use?C#?destructor?syntax?for?finalization?code.?
// ?This?destructor?will?run?only?if?the?Dispose?method?
// ?does?not?get?called.?
// ?It?gives?your?base?class?the?opportunity?to?finalize.?
// ?Do?not?provide?destructors?in?types?derived?from?this?class.?
~ BaseResource()?
{?
// ?Do?not?re-create?Dispose?clean-up?code?here.?
// ?Calling?Dispose(false)is?optimal?in?terms?of?
// ?readability?and?maintainability.?
Dispose( false );?
}
?

// ?Allow?your?Dispose?method?to?be?called?multiple?times,?
// ?but?throw?an?exception?if?the?object?has?been?disposed.?
// ?Whenever?you?do?something?with?this?class,?
// ?check?to?see?if?it?has?been?disposed.?
public ? void ?DoSomething()?
{?
if ( this .disposed)?
{?
throw ? new ?ObjectDisposedException();?
}
?
}
?
}
?

// ?Design?pattern?for?a?derived?class.?
// ?Note?that?this?derived?class?inherently?implements?the?
// ?IDisposable?interface?because?it?is?implemented?in?the?base?class.?
public ? class ?MyResourceWrapper:?BaseResource?
{?
// ?A?managed?resource?that?you?add?in?this?derived?class.?
private ?ManagedResource?addedManaged;?
// ?A?native?unmanaged?resource?that?you?add?in?this?derived?class.?
private ?NativeResource?addedNative;?
private ? bool ?disposed? = ? false ;?

// ?Constructor?for?this?object.?
public ?MyResourceWrapper()?
{?
// ?Insert?appropriate?constructor?code?here.?
}
?

protected ? override ? void ?Dispose( bool ?disposing)?
{?
if ( ! this .disposed)?
{?
try ?
{?
if (disposing)?
{?
// ?Release?the?managed?resources?you?added?in?
// ?this?derived?class?here.?
addedManaged.Dispose();?
}
?
// ?Release?the?native?unmanaged?resources?you?added?
// ?in?this?derived?class?here.?
CloseHandle(addedNative);?
this .disposed? = ? true ;?
}
?
finally ?
{?
// ?Call?Dispose?on?your?base?class.?
base .Dispose(disposing);?
}
?
}
?
}
?
}
?

// ?This?derived?class?does?not?have?a?Finalize?method?
 對于finalize()方法的另一個問題是開發人員不知道什么時候它將被調用。它不像C++中的析構函數在刪除一個對象時被調用。為了解決這個問題,在.Net中提供了一個接口IDisposable。微軟建議在實現帶有fianlize()方法的類的時侯按照下面的模式定義對象:


public?class?Class1?:?IDisposable?
{
 
public?Class1()
 
{
 }


 
~Class1?()
 
{
  
//垃圾回收器將調用該方法,因此參數需要為false。
  Dispose?(false);
 }


 
//該方法定義在IDisposable接口中。
 public?void?Dispose?()
 
{
  
//該方法由程序調用,在調用該方法之后對象將被終結。
  
//因為我們不希望垃圾回收器再次終結對象,因此需要從終結列表中去除該對象。
  GC.SuppressFinalize?(this);
  
//因為是由程序調用該方法的,因此參數為true。
  Dispose?(true);
 }


 
//所有與回收相關的工作都由該方法完成
 private?void?Dispose(bool?disposing)
 ??
{
  
lock(this)?//避免產生線程錯誤。
  {
   
if?(disposing)
   
{
    
//需要程序員完成釋放對象占用的資源。
   }


  
//對象將被垃圾回收器終結。在這里添加其它和清除對象相關的代碼。
 }

}

}




現在我們了解了垃圾回收器工作的基本原理,接下來讓我們看一看垃圾回收器內部是如何工作的。目前有很多種類型的垃圾回收器。微軟實現了一種生存期垃圾回收器(Generational Garbage Collector)。生存期垃圾回收器將內存分為很多個托管堆,每一個托管堆對應一種生存期等級。生存期垃圾回收器遵循著下面的原則:

  新生成的對象,其生存期越短;而對象生成時間越長的對象,其生存期也就越長。對于垃圾回收器來說,回收一部分對象總是比回收全部對象要快,因此垃圾回收器對于那些生存期短的對象回收的頻率要比生存期長的對象的回收頻率高。

  .Net中的垃圾回收器中目前有三個生存期等級:0,1和2。0、1、2等級對應的托管堆的初始化大小分別是256K,2M和10M。垃圾回收器在發現改變大小能夠提高性能的話,會改變托管堆的大小。例如當應用程序初始化了許多小的對象,并且這些對象會被很快回收的話,垃圾回收器就會將0等級的托管堆變為128K,并且提高回收的頻率。如果情況相反,垃圾回收器發現在0等級的托管堆中不能回收很多空間時,就會增加托管堆的大小。

在應用程序初始化的之前,所有等級的托管堆都是空的。當對象被初始化的時候,他們會按照初始化的先后順序被放入等級為0的托管堆中。在托管堆中對象的存放是連續的,這樣使得托管堆存取對象的速度很快,因為托管對不必對內存進行搜索。垃圾回收器中保存了一個指針指向托管堆中最后一個對象之后的內存空間。圖一中顯示了一個包含四個對象的0等級的托管堆。


圖一 包含四個對象的托管堆

當0等級托管堆被對象填滿后,例如候程序初始化了新的對象,使0等級托管堆的大小超過了256K,垃圾回收器會檢查托管堆中的所有對象,看是否有對象可以回收。當開始回收操作時,如前面提到的,垃圾回收器會找出根節點和根節點直接或間接引用了的對象,然后將這些對象轉移到1等級托管堆中,并將0等級托管堆的指針移到最開始的位置以清除所有的對象。同時垃圾回收器會壓縮1等級托管堆以保證所有對象之間沒有內存空隙。當1等級托管堆滿了之后,會將對象轉移到2等級的托管堆。

  例如在圖一之后,垃圾回收器開始回收對象,假定D對象將被回收,同時程序創建了E和F對象。這時候托管堆中的對象如圖二所示。


圖二 回收對象后的0等級和1等級托管堆

  然后程序創建了新的對象G和H,再一次觸發了垃圾回收器。對象E將被回收。這時候托管堆中的對象如圖三所示。



  生存期垃圾回收器的原則也有例外的情況。當對象的大小超過84K時,對象會被放入"大對象區"。大對象區中的對象不會被垃圾回收器回收,也不會被壓縮。這樣做是為了強制垃圾回收器只能回收小對象以提高程序的性能。

  控制垃圾回收器

  在.Net框架中提供了很多方法使開發人員能夠直接控制垃圾回收器的行為。通過使用GC.Collect()或GC.Collect(int GenerationNumber)開發人員可以強制垃圾回收器對所有等級的托管堆進行回收操作。在大多數的情況下開發人員不需要干涉垃圾回收器的行為,但是有些情況下,例如當程序進行了非常復雜的操作后希望確認內存中的垃圾對象已經被回收,就可以使用上面的方法。另一個方法是GC.WaitForPendingFinalizers(),它可以掛起當前線程,直到處理完成器隊列的線程清空該隊列為止。

  使用垃圾回收器最好的方法就是跟蹤程序中定義的對象,在程序不需要它們的時候手動釋放它們。例如程序中的一個對象中有一個字符串屬性,該屬性會占用一定的內存空間。當該屬性不再被使用時,開發人員可以在程序中將其設定為null,這樣垃圾回收器就可以回收該字符串占用的空間。另外,如果開發人員確定不再使用某個對象時,需要同時確定沒有其它對象引用該對象,否則垃圾回收器不會回收該對象。

  另外值得一提的是finalize()方法應該在較短的時間內完成,這是因為垃圾回收器給finalize()方法限定了一個時間,如果finalize()方法在規定時間內還沒有完成,垃圾回收器會終止運行finalize()方法的線程。在下面這些情況下程序會調用對象的finalize()方法:

   0等級垃圾回收器已滿

   程序調用了執行垃圾回收的方法

   公共語言運行庫正在卸載一個應用程序域

   公共語言運行庫正在被卸載

posted on 2006-04-30 15:52 夢在天涯 閱讀(2288) 評論(0)  編輯 收藏 引用 所屬分類: C#/.NET

公告

EMail:itech001#126.com

導航

統計

  • 隨筆 - 461
  • 文章 - 4
  • 評論 - 746
  • 引用 - 0

常用鏈接

隨筆分類

隨筆檔案

收藏夾

Blogs

c#(csharp)

C++(cpp)

Enlish

Forums(bbs)

My self

Often go

Useful Webs

Xml/Uml/html

搜索

  •  

積分與排名

  • 積分 - 1816192
  • 排名 - 5

最新評論

閱讀排行榜

青青草原综合久久大伊人导航_色综合久久天天综合_日日噜噜夜夜狠狠久久丁香五月_热久久这里只有精品
  • <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>
              老鸭窝毛片一区二区三区| 亚洲国产日韩在线| 亚洲区第一页| 国内精品久久久久影院 日本资源| 亚洲第一成人在线| 国产一区深夜福利| 亚洲一区久久| 亚洲一二三区在线| 欧美国产第一页| 裸体歌舞表演一区二区| 国产欧美一区二区三区久久人妖 | 欧美色图一区二区三区| 欧美~级网站不卡| 国产一区二区三区四区三区四| 在线中文字幕一区| 国产精品99久久不卡二区| 欧美国产欧美亚洲国产日韩mv天天看完整 | 亚洲天堂av在线免费观看| 蜜臀久久99精品久久久久久9| 久久免费视频网站| 国产一区再线| 久久久久国产精品午夜一区| 久久精品理论片| 国产一区二区三区成人欧美日韩在线观看| 亚洲线精品一区二区三区八戒| 亚洲一区二区三区精品动漫| 欧美日韩一卡| 亚洲少妇最新在线视频| 午夜精品久久久久久久99热浪潮| 欧美色视频在线| 亚洲视频高清| 久久高清福利视频| 国产综合久久久久影院| 久久久99爱| 欧美国产欧美综合| 日韩视频专区| 国产精品高潮呻吟久久av黑人| 一区二区日本视频| 欧美一区二区三区在线| 国产一区二区中文字幕免费看| 久久aⅴ国产欧美74aaa| 乱中年女人伦av一区二区| 亚洲人成在线播放网站岛国| 欧美精品性视频| 亚洲午夜免费福利视频| 久久精品国产v日韩v亚洲 | 亚洲电影观看| 欧美精品日日鲁夜夜添| 亚洲图片激情小说| 久久全球大尺度高清视频| 亚洲丰满少妇videoshd| 欧美另类变人与禽xxxxx| 亚洲视频在线观看一区| 久久久久国产精品午夜一区| 亚洲国产影院| 国产精品毛片va一区二区三区| 久久国产精品免费一区| 亚洲欧洲日本在线| 欧美一区网站| 亚洲韩国精品一区| 国产精品福利av| 美国三级日本三级久久99| av成人福利| 麻豆精品在线视频| 亚洲一区二区在线观看视频| 国内自拍视频一区二区三区| 欧美黄在线观看| 欧美伊久线香蕉线新在线| 亚洲精品国产精品乱码不99| 久久大香伊蕉在人线观看热2| 亚洲国产精品va在看黑人| 国产精品xxx在线观看www| 久久中文精品| 欧美一区二区三区在线视频| 亚洲精品一区二区三| 久久综合色播五月| 午夜亚洲性色福利视频| 日韩午夜电影| 韩日精品在线| 国产精品日韩欧美一区| 欧美激情亚洲| 久久综合九色| 欧美一区二区女人| 一区二区三区.www| 亚洲国产日韩欧美在线动漫| 久久久精品日韩欧美| 亚洲免费在线电影| 亚洲激情第一区| 禁断一区二区三区在线| 国产区在线观看成人精品| 欧美日本不卡| 欧美大片网址| 另类亚洲自拍| 久久永久免费| 久久国产日韩| 久久国产精品一区二区三区| 亚洲一区免费看| 一区二区欧美日韩| 洋洋av久久久久久久一区| 亚洲国产日韩欧美在线动漫| 蜜臀99久久精品久久久久久软件| 久久国产精品网站| 久久国产天堂福利天堂| 欧美伊人久久| 久久久久久久高潮| 久久天天躁狠狠躁夜夜av| 久久久久久久久综合| 久久九九国产精品| 久久女同精品一区二区| 久久蜜桃资源一区二区老牛 | 亚洲人成啪啪网站| 亚洲人成免费| 一本色道久久综合精品竹菊| 99国产一区| 一区二区三区四区精品| 中文日韩电影网站| 亚洲欧美bt| 久久av一区二区三区亚洲| 久久久久成人精品免费播放动漫| 久久精品日韩| 欧美国产精品v| 欧美日韩国产一区精品一区| 欧美天天视频| 国产欧亚日韩视频| 在线观看亚洲专区| 亚洲美女中文字幕| 亚洲欧美国产日韩天堂区| 久久精品国产亚洲精品| 久久综合亚洲社区| 91久久在线观看| 制服诱惑一区二区| 久久久久久久91| 欧美激情第1页| 国产精品视频精品| 亚洲第一中文字幕在线观看| 99精品视频免费| 欧美一区午夜精品| 欧美成人午夜视频| 一区二区高清视频在线观看| 欧美在线在线| 欧美另类videos死尸| 国产美女扒开尿口久久久| **性色生活片久久毛片| 亚洲天堂成人| 欧美aⅴ99久久黑人专区| 99精品国产在热久久下载| 欧美一区二区三区四区视频| 欧美v亚洲v综合ⅴ国产v| 国产精品爽爽爽| 亚洲国产一区二区三区在线播| 亚洲一区国产| 欧美黄色aa电影| 亚洲欧美日韩在线不卡| 欧美电影在线观看完整版| 国产欧美一区在线| 亚洲作爱视频| 蜜臀av性久久久久蜜臀aⅴ| 在线中文字幕日韩| 欧美大片国产精品| 国产一区二区| 亚洲欧美日韩精品一区二区| 欧美成人小视频| 欧美在线不卡| 国产精品区二区三区日本| 亚洲片在线观看| 老司机午夜精品视频在线观看| 亚洲精品中文字幕女同| 狂野欧美激情性xxxx欧美| 国产欧美成人| 午夜精品视频网站| 亚洲免费电影在线观看| 六月丁香综合| 亚洲第一免费播放区| 久久精品论坛| 亚洲欧美日产图| 国产精品久久久久影院色老大| 日韩视频欧美视频| 欧美国产日韩视频| 久久亚洲私人国产精品va| 国产深夜精品| 欧美一区二区日韩一区二区| 99在线|亚洲一区二区| 欧美精品手机在线| 亚洲另类春色国产| 亚洲欧洲美洲综合色网| 欧美电影在线观看完整版| 亚洲电影免费观看高清完整版在线观看| 欧美一区二区三区男人的天堂| 亚洲深夜激情| 国产精品久久久久久久一区探花| 亚洲深夜福利在线| 日韩视频不卡中文| 欧美午夜激情视频| 亚洲综合电影| 亚洲欧美日韩精品久久久久| 国产精品视频久久一区| 欧美在线一区二区| 欧美在线观看一二区| 激情文学一区| 亚洲福利国产精品|