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

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>
              亚洲无线观看| 久久综合一区| 欧美成人免费网| 免费成人毛片| 亚洲人成毛片在线播放| 免费在线成人| 亚洲欧洲在线播放| 亚洲视频一区| 久久久久久久网站| 欧美精品三级日韩久久| 国产精品v一区二区三区| 国产精品自拍网站| 亚洲国产欧美一区二区三区同亚洲 | 亚洲新中文字幕| 欧美资源在线观看| 欧美激情免费观看| 国产日韩欧美精品综合| 亚洲国产一区二区精品专区| 亚洲一区二区三区四区五区黄| 欧美在线影院| 亚洲黄色影院| 欧美一区不卡| 欧美特黄a级高清免费大片a级| 韩国av一区| 亚洲视频免费| 欧美二区在线播放| 午夜精品国产更新| 欧美日韩精品一区二区三区四区| 亚洲剧情一区二区| 国产精品天天看| 亚洲国产精品久久久久| 在线亚洲精品| 欧美成人久久| 欧美在线观看网站| 欧美午夜无遮挡| 亚洲日本乱码在线观看| 久久成人18免费网站| 亚洲精品久久久久久久久久久| 久久国产66| 国产精品亚洲综合| 亚洲一区二区精品视频| 亚洲国产欧洲综合997久久| 校园春色国产精品| 国产精品日韩一区二区三区| 一本高清dvd不卡在线观看| 老妇喷水一区二区三区| 先锋亚洲精品| 国产欧美丝祙| 欧美尤物巨大精品爽| 亚洲小说区图片区| 国产精品每日更新| 亚洲午夜性刺激影院| 91久久久久久久久| 欧美大片免费观看| 亚洲人成免费| 亚洲国语精品自产拍在线观看| 久久精彩免费视频| 激情综合色综合久久综合| 久久久青草青青国产亚洲免观| 午夜精品久久久久久| 国产欧美日韩综合一区在线观看| 欧美一区二区高清| 欧美一区二区三区播放老司机| 国产欧美午夜| 久久综合久久美利坚合众国| 久久精品人人| 亚洲黄色成人久久久| 亚洲国产欧美在线| 欧美日韩在线高清| 欧美专区日韩视频| 久久免费国产| 亚洲精美视频| 一本久久青青| 国产亚洲福利一区| 免费久久99精品国产| 免费视频一区二区三区在线观看| 99精品国产热久久91蜜凸| 亚洲免费观看高清在线观看| 国产精品久久中文| 久久天堂成人| 欧美福利一区二区三区| 亚洲免费小视频| 久久精品女人天堂| 亚洲精品日韩久久| 亚洲专区一区二区三区| 精品91免费| 99精品欧美一区| 狠狠色香婷婷久久亚洲精品| 久久激情中文| 亚洲视频精品在线| 亚洲大片av| 国产精品激情偷乱一区二区∴| 性xx色xx综合久久久xx| 久久久久国产一区二区| 一区二区三区日韩欧美精品| 亚洲欧美制服另类日韩| 91久久久久久久久久久久久| 亚洲视频免费| 亚洲精品一区二区三| 亚洲欧美一区二区视频| 99在线|亚洲一区二区| 欧美专区在线观看一区| 一区二区三区视频在线| 久久久久综合一区二区三区| 亚洲综合国产激情另类一区| 老司机午夜精品视频| 欧美一区二区三区视频免费| 久热精品视频| 久久精品国产v日韩v亚洲| 欧美日本高清一区| 欧美成年人视频网站欧美| 国产精品一区二区久久精品| 亚洲国产精品久久| 国产自产精品| 亚洲欧美日韩综合国产aⅴ| 亚洲精品一品区二品区三品区| 久久国产日本精品| 欧美一级在线视频| 欧美视频在线观看 亚洲欧| 欧美国产视频在线| 一区二区三区在线不卡| 午夜免费久久久久| 亚洲欧美中日韩| 欧美三区美女| 亚洲美女中文字幕| 日韩亚洲欧美成人| 欧美成人蜜桃| 亚洲高清一区二| 在线播放亚洲一区| 久久精品免费播放| 久久综合亚州| 黄色成人小视频| 久久国产日韩欧美| 另类专区欧美制服同性| 国内精品视频在线播放| 欧美在线不卡视频| 久久乐国产精品| 一色屋精品视频在线看| 久久九九免费视频| 免费成人av资源网| 亚洲国产天堂久久国产91| 久久欧美肥婆一二区| 免费成人在线观看视频| 在线日本成人| 欧美好骚综合网| 亚洲精品视频在线看| 一区二区三区.www| 国产精品麻豆va在线播放| 亚洲欧美国产制服动漫| 久久久久久久综合色一本| 伊人伊人伊人久久| 欧美精品v国产精品v日韩精品| 亚洲欧洲综合另类在线| 亚洲视频综合| 国产亚洲激情在线| 欧美成人高清视频| 亚洲国产欧美在线人成| av不卡在线看| 久久亚洲一区二区三区四区| 欧美国产另类| 国产精品99久久久久久久女警| 国产精品欧美久久| 久久精品国产一区二区三| 亚洲成色777777女色窝| 宅男噜噜噜66一区二区66| 国产女人水真多18毛片18精品视频| 欧美一级理论片| 亚洲福利国产| 欧美一区免费视频| 亚洲二区免费| 国产精品黄色| 麻豆成人在线播放| 亚洲午夜精品视频| 欧美大胆a视频| 午夜精品福利视频| 亚洲第一色在线| 国产精品欧美一区二区三区奶水| 久久久久se| 亚洲一区二区欧美| 亚洲高清在线精品| 久久精品国产999大香线蕉| 99国产一区| 亚洲国产精品第一区二区| 国产精品国产三级国产普通话99| 久久久精品久久久久| 国产精品99久久久久久久久久久久 | 日韩亚洲国产欧美| 尤物精品国产第一福利三区| 欧美视频网站| 欧美电影打屁股sp| 久久精品国产精品亚洲综合| 日韩图片一区| 亚洲国产精品久久久久秋霞蜜臀| 久久精品在这里| 小黄鸭精品aⅴ导航网站入口| 日韩西西人体444www| 一色屋精品亚洲香蕉网站| 国产日韩精品久久| 国产精品入口66mio| 欧美性事在线|