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

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 夢在天涯 閱讀(2278) 評論(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

搜索

  •  

積分與排名

  • 積分 - 1812148
  • 排名 - 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>
              欧美在线视频不卡| 亚洲精品视频一区二区三区| 亚洲视频第一页| 国产精品高潮呻吟| 欧美中文在线免费| 久久se精品一区精品二区| 狠狠色狠狠色综合| 亚洲国产精品激情在线观看| 欧美国产日韩一区二区三区| 亚洲无玛一区| 久久成人人人人精品欧| 亚洲国产日韩欧美| 一区电影在线观看| 国产亚洲一区在线播放| 欧美黄色小视频| 欧美午夜久久久| 毛片精品免费在线观看| 欧美不卡福利| 久久成人国产| 免费在线国产精品| 欧美一区二区三区在线| 老牛影视一区二区三区| 亚洲一区二区三区在线播放| 久久精品中文字幕一区| 日韩亚洲国产欧美| 欧美一区二视频| 亚洲一级黄色av| 美国十次了思思久久精品导航| 亚洲婷婷综合色高清在线 | 欧美永久精品| 欧美大片免费观看| 久久久亚洲综合| 欧美日韩精品在线观看| 久久先锋影音| 国产美女精品人人做人人爽| 亚洲激情欧美激情| 韩国免费一区| 午夜在线不卡| 亚洲在线播放电影| 欧美激情精品久久久久久变态| 久久国产色av| 国产精品视频网址| 99pao成人国产永久免费视频| 精品999久久久| 性欧美激情精品| 亚洲欧美日韩高清| 欧美片在线播放| 欧美激情视频在线免费观看 欧美视频免费一| 国产精品亚洲激情| av成人老司机| 亚洲视频一区二区| 欧美另类变人与禽xxxxx| 欧美激情第9页| 欧美日韩国产另类不卡| 欧美精品一区二区三区久久久竹菊 | 国产精品v欧美精品v日本精品动漫| 欧美成人国产| 亚洲高清视频一区| 久久亚洲二区| 欧美本精品男人aⅴ天堂| 国模精品一区二区三区| 久久成人人人人精品欧| 久久噜噜噜精品国产亚洲综合| 国产区亚洲区欧美区| 亚洲欧美国产制服动漫| 欧美一区二区三区视频在线| 国产欧美日韩亚洲精品| 欧美一区二区视频在线| 久久亚洲私人国产精品va| 国产一区在线看| 久久综合亚州| 亚洲精品你懂的| 日韩视频在线一区| 欧美日韩麻豆| 亚洲综合第一| 老司机精品久久| 亚洲乱亚洲高清| 欧美午夜视频一区二区| 亚洲永久网站| 久久综合一区| 99视频精品在线| 国产精品久久久久影院色老大| 亚洲欧美日韩成人| 美女视频黄a大片欧美| 亚洲欧洲精品一区二区| 国产精品成人久久久久| 亚洲欧美日韩视频一区| 老司机成人网| 在线综合+亚洲+欧美中文字幕| 国产精品久久久久影院亚瑟 | 久久精品夜色噜噜亚洲a∨| 免费一区视频| 亚洲图中文字幕| 国产在线视频欧美| 欧美激情一区二区三区四区| 亚洲一区免费网站| 欧美成在线视频| 亚洲欧美国产精品桃花| 在线观看91精品国产麻豆| 欧美日韩国产综合视频在线观看中文 | 久久精品在线观看| 日韩视频精品在线观看| 久久精品免费看| 一本一本久久a久久精品综合妖精| 国产农村妇女精品一二区| 欧美www在线| 欧美一区二区三区视频免费| 亚洲欧洲精品一区二区三区不卡| 久久se精品一区精品二区| 91久久在线视频| 国产一区二区三区日韩欧美| 欧美日韩在线观看一区二区三区 | 午夜国产精品视频| 99爱精品视频| 今天的高清视频免费播放成人| 欧美系列精品| 欧美高清在线视频| 久久爱另类一区二区小说| 一区二区三区日韩在线观看| 欧美91大片| 久久在线观看视频| 性欧美1819性猛交| 亚洲视频精品| 一本久道久久综合中文字幕| 亚洲国产精品免费| 国产综合视频| 国产一区二区三区直播精品电影 | 欧美日韩福利在线观看| 久久综合一区二区| 久久精品免费电影| 午夜亚洲福利| 午夜在线播放视频欧美| 亚洲欧美国产视频| 亚洲综合久久久久| 亚洲影院在线观看| 亚洲欧美日韩国产一区| 亚洲欧美日韩成人| 亚洲中午字幕| 午夜伦欧美伦电影理论片| 亚洲欧美日韩成人高清在线一区| 亚洲一区二区黄| 亚洲欧美国产另类| 欧美亚洲三区| 久久精品男女| 久久综合九色综合欧美狠狠| 久久综合久久综合久久| 另类春色校园亚洲| 欧美成人精品福利| 欧美日本三区| 国产精品福利久久久| 国产精品影音先锋| 激情欧美日韩一区| 亚洲国产精品一区在线观看不卡| 亚洲国产一区二区精品专区| 亚洲精品护士| 亚洲资源在线观看| 久久精品2019中文字幕| 久久综合久久88| 亚洲国产专区| 亚洲图片欧洲图片日韩av| 亚洲一区在线直播| 久久久99免费视频| 欧美激情久久久久久| 欧美午夜剧场| 影音先锋欧美精品| 日韩午夜电影在线观看| 亚洲欧美国产制服动漫| 久久精品在线视频| 亚洲第一区中文99精品| 亚洲无线视频| 久久先锋资源| 国产精品久久久久高潮| 在线国产精品播放| 亚洲影视在线| 欧美不卡一卡二卡免费版| 亚洲毛片在线| 久久久久久久久一区二区| 欧美精品成人91久久久久久久| 国产精品国产自产拍高清av王其 | 欧美性猛交xxxx免费看久久久 | 欧美性猛交视频| 在线成人激情| 亚洲愉拍自拍另类高清精品| 免费成人在线视频网站| 亚洲视频狠狠| 欧美国产综合一区二区| 国产美女精品一区二区三区| 亚洲日韩成人| 久久一区二区三区超碰国产精品| 国产精品美女一区二区| 亚洲激情成人| 久久爱www久久做| 亚洲电影在线播放| 欧美一区二区三区免费大片| 欧美色精品天天在线观看视频| 亚洲韩国日本中文字幕| 久久久综合免费视频| 亚洲影视九九影院在线观看| 欧美日韩色婷婷| 亚洲精品欧美|