久久精品国产精品国产精品污,男人扒开添女人下部免费视频,一级国产69式性姿势免费视频,夜鲁夜鲁很鲁在线视频 视频,欧美丰满少妇一区二区三区,国产偷国产偷亚洲高清人乐享,中文 在线 日韩 亚洲 欧美,熟妇人妻无乱码中文字幕真矢织江,一区二区三区人妻制服国产

歡迎訪問 生活随笔!

生活随笔

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

C#

C#垃圾回收学习总结

發布時間:2025/4/14 C# 18 豆豆
生活随笔 收集整理的這篇文章主要介紹了 C#垃圾回收学习总结 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

淺談C#垃圾回收

http://www.cnblogs.com/cuiyiming/archive/2013/03/26/2981931.html


  理解C#垃圾回收機制我們首先說一下CLR(公共語言運行時,Common Language Runtime)它和Java虛擬機一樣是一個運行時環境,核心功能包括:內存管理、程序集加載、安全性、異步處理和線程同步。

CTS(Common Type System)通用類型系統,它把.Net中的類型分為2大類,引用類型與值類型。.Net中所有類型都間接或直接派生至System.Object類型。所有的值類型都是System.ValueType的子類,而System.ValueType本身卻是引用類型。

托管資源:
  由CLR管理的存在于托管堆上的稱為托管資源,注意這里有2個關鍵點,第一是由CLR管理,第二存在于托管堆上。托管資源的回收工作是不需要人工干預的,CLR會在合適的時候調用GC(垃圾回收器)進行回收。

非托管資源:
  非托管資源是不由CLR管理,例如:Image Socket, StreamWriter, Timer, Tooltip, 文件句柄, GDI資源, 數據庫連接等等資源(這里僅僅列舉出幾個常用的)。這些資源GC是不會自動回收的,需要手動釋放。

通過上面的講述總結一下,第一,GC(垃圾回收器)只回收托管資源,不回收非托管資源。第二,GC回收是要在合適的時候(CLR覺得應該進行回收的時候)才進行回收。那么非托管如何進行回收呢?下面就讓我一一道來。

在.Net中釋放非托管資源主要有2種方式,Dispose,Finalize

Dispose方法,對象要繼承IDisposable接口,也就會自動調用Dispose方法。

Class Suifeng:System.IDisposable {#region IDisposable 成員public void Dispose(){//}#endregion }Suifeng suiFeng= new Suifeng (); suiFeng.Dispose();

也可以使用Using語句
(using Suifeng suiFeng= new Suifeng())
{
? ? ?//
}


Finalize()方法

MSDN上的定義是允許對象在“垃圾回收”回收之前嘗試釋放資源并執行其他清理操作。
它的本質就是析構函數

class Car
{
? ? ~Car() ?// destructor
? ? {
? ? ? ? // cleanup statements...
? ? }
}


該析構函數隱式地對對象的基類調用 Finalize。 這樣,前面的析構函數代碼被隱式地轉換為以下代碼:

protected override void Finalize()
{
? ? try
? ? {
? ? ? ? // Cleanup statements...
? ? }
? ? finally
? ? {
? ? ? ? base.Finalize();
? ? }
}

在.NET中應該盡可能的少用析構函數釋放資源,MSDN2上有這樣一段話:
  實現 Finalize 方法或析構函數對性能可能會有負面影響,因此應避免不必要地使用它們。用 Finalize 方法回收對象使用的內存需要至少兩次垃圾回收。當垃圾回收器執行回收時,它只回收沒有終結器的不可訪問對象的內存。這時,它不能回收具有終結器的不可


訪問對象。它改為將這些對象的項從終止隊列中移除并將它們放置在標為準備終止的對象列表中。該列表中的項指向托管堆中準備被調用其終止代碼的對象。垃圾回收器為此列表中的對象調用 Finalize 方法,然后,將這些項從列表中移除。后來的垃圾回收將確定終止


的對象確實是垃圾,因為標為準備終止對象的列表中的項不再指向它們。在后來的垃圾回收中,實際上回收了對象的內存。


  所以有析構函數的對象,需要兩次,第一次調用析構函數,第二次刪除對象。而且在析構函數中包含大量的釋放資源代碼,會降低垃圾回收器的工作效率,影響性能。所以對于包含非托管資源的對象,最好及時的調用Dispose()方法來回收資源,而不是依賴垃圾回收


器。
? ?在一個包含非托管資源的類中,關于資源釋放的標準做法是:
? ?繼承IDisposable接口;
? ?實現Dispose()方法,在其中釋放托管資源和非托管資源,并將對象本身從垃圾回收器中移除(垃圾回收器不在回收此資源);
? ?實現類析構函數,在其中釋放非托管資源。
? ?請看MSDN上的源碼 ??

Public class BaseResource:IDisposable
? ?{
? ? ? PrivateIntPtr handle; // 句柄,屬于非托管資源
? ? ? PrivateComponet comp; // 組件,托管資源
? ? ? Privateboo isDisposed = false; // 是否已釋放資源的標志
? ? ? ?
? ? ? PublicBaseResource
? ? ? {
? ? ? }
? ? ? ??
? ? ? ?//實現接口方法
? ? ? ?//由類的使用者,在外部顯示調用,釋放類資源
? ? ? ?Public void Dispose()
? ? ? ?{
? ? ? ? ? ?Dispose(true);// 釋放托管和非托管資源
? ? ? ? ? ? ? ? ? ? ? ? ? ?
? ? ? ? ? //將對象從垃圾回收器鏈表中移除,
? ? ? ? ?// 從而在垃圾回收器工作時,只釋放托管資源,而不執行此對象的析構函數


? ? ? ? ? ? GC.SuppressFinalize(this);
? ? ? ? ?}
? ? ? ??
? ? ? ? ?//由垃圾回收器調用,釋放非托管資源


? ? ? ?~BaseResource()
? ? ? ? {
? ? ? ? ? ?Dispose(false);// 釋放非托管資源
? ? ? ? }
? ? ? ??
? ? ?//參數為true表示釋放所有資源,只能由使用者調用
? ? //參數為false表示釋放非托管資源,只能由垃圾回收器自動調用
? ?//如果子類有自己的非托管資源,可以重載這個函數,添加自己的非托管資源的釋放
? //但是要記住,重載此函數必須保證調用基類的版本,以保證基類的資源正常釋放
? ? Protectedvirtual void Dispose(bool disposing)
? ? {
? ? ? ?If(!this.disposed)// 如果資源未釋放 這個判斷主要用了防止對象被多次釋放
? ? ? ? ?{
? ? ? ? ? ? If(disposing)
? ? ? ? ? ? {
? ? ? ? ? ? ? ?Comp.Dispose();// 釋放托管資源
? ? ? ? ? ? ?}
? ? ? ? ? ? ? ? ? ? ? ? ? ?
? ? ? ? ? ?closeHandle(handle);// 釋放非托管資源
? ? ? ? ? ?handle= IntPtr.Zero;
? ? ? ? ? ?}
? ? ? ? ? this.disposed= true; // 標識此對象已釋放
? ? ? }
? }


參考了MSDN和網上的一些資料,第一次寫博文請各位大俠多多指點!


========

c# -- 對象銷毀和垃圾回收

http://www.cnblogs.com/yang_sy/p/3784151.html
有些對象需要顯示地銷毀代碼來釋放資源,比如打開的文件資源,鎖,操作系統句柄和非托管對象。在.NET中,這就是所謂的對象銷毀,它通過IDisposal接口來實現。不再使用的對象所占用的內存管理,必須在某個時候回收;這個被稱為無用單元收集的功能由CLR執行

。

對象銷毀和垃圾回收的區別在于:對象銷毀通常是明確的策動;而垃圾回收完全是自動地。換句話說,程序員負責釋放文件句柄,鎖,以及操作系統資源;而CLR負責釋放內存。

本章將討論對象銷毀和垃圾回收,還描述了C#處理銷毀的一個備選方案--Finalizer及其模式。最后,我們討論垃圾回收器和其他內存管理選項的復雜性。

對象銷毀 垃圾回收
1)IDisposal接口
2) Finalizer 垃圾回收
對象銷毀用于釋放非托管資源 垃圾回收用于自動釋放不再被引用的對象所占用的內存;并且垃圾回收什么時候執行時不可預計的
為了彌補垃圾回收執行時間的不確定性,可以在對象銷毀時釋放托管對象占用的內存 ?
?

IDisposal,Dispose和Close

image

.NET Framework定義了一個特定的接口,類型可以使用該接口實現對象的銷毀。該接口的定義如下:

public interface IDisposable
{
void Dispose();
}
C#提供了鴘語法,可以便捷的調用實現了IDisposable的對象的Dispose方法。比如:

using (FileStream fs = new FileStream ("myFile.txt", FileMode.Open))
{
// ... Write to the file ...
}
編譯后的代碼與下面的代碼是一樣的:


復制代碼
FileStream fs = new FileStream ("myFile.txt", FileMode.Open);
try
{
// ... Write to the file ...
}
finally
{
if (fs != null) ((IDisposable)fs).Dispose();
}
復制代碼
finally語句確保了Dispose方法的調用,及時發生了異常,或者代碼在try語句中提前返回。


在簡單的場景中,創建自定義的可銷毀的類型值需要實現IDisposable接口即可


sealed class Demo : IDisposable
{
public void Dispose()
{
// Perform cleanup / tear-down.
...
}
}


請注意,對于sealed類,上述模式非常適合。在本章后面,我們會介紹另外一種銷毀對象的模式。對于非sealed類,我們強烈建議時候后面的那種銷毀對象模式,否則在非sealed類的子類中,也希望實現銷毀時,會發生非常詭異的問題。


對象銷毀的標準語法


Framework在銷毀對象的邏輯方面遵循一套規則,這些規則并不限用于.NET Framework或C#語言;這些規則的目的是定義一套便于使用的協議。這些協議如下:


一旦銷毀,對象不可恢復。對象不能被再次激活,調用對象的方法或者屬性拋出ObjectDisposedException異常
重復地調用對象的Disposal方法會導致錯誤
如果一個可銷毀對象x包含,或包裝,或處理另外一個可銷毀對象y,那么x的Dispose方法自動調用x的Dispose方法,除非另有指令(不銷毀y)
這些規則同樣也適用于我們平常創建自定義類型,盡管它并不是強制性的。沒有誰能阻止你編寫一個不可銷毀的方法;然而,這么做,你的同事也許會用高射炮攻擊你。


對于第三條規則,一個容器對象自動銷毀其子對象。最好的一個例子就是,windows容器對象比如Form對著Panel。一個容器對象可能包含多個子控件,那你也不需要顯示地銷毀每個字對象:關閉或銷毀父容器會自動關閉其子對象。另外一個例子就是如果你在


DeflateStream包裝了FileStream,那么銷毀DeflateStream時,FileStream也會被銷毀--除非你在構造器中指定了其他的指令。


Close和Stop


有一些類型除了Dispose方法之外,還定義了Close方法。Framework對于Close方法并沒有保持完全一致性,但在幾乎所有情況下,它可以:


要么在功能上與Dispose一致
或只是Dispose的一部分功能
對于后者一個典型的例子就是IDbConnecton類型,一個Closed的連接可以再次被打開;而一個Disposed的連接對象則不能。另外一個例子就是Windows程序使用ShowDialog的激活某個窗口對象:Close方法隱藏該窗口;而Dispose釋放窗口所使用的資源。


有一些類定義Stop方法(比如Timer或HttpListener)。與Dipose方法一樣,Stop方法可能會釋放非托管資源;但是與Dispose方法不同的是,它允許重新啟動。


何時銷毀對象


銷毀對象應該遵循的規則是“如有疑問,就銷毀”。一個可以被銷毀的對象--如果它可以說話--那么將會說這些內容:


“如果你結束對我的使用,那么請讓我知道。如果只是簡單地拋棄我,我可能會影響其他實例對象、應用程序域、計算機、網絡、或者數據庫”


如果對象包裝了非托管資源句柄,那么經常會要求銷毀,以釋放句柄。例子包括Windows Form控件、文件流或網絡流、網絡sockets,GDI+畫筆、GDI+刷子,和bitmaps。與之相反,如果一個類型是可銷毀的,那么它會經常(但不總是)直接或間接地引用非托管句柄。這


是由于非托管句柄對操作系統資源,網絡連接,以及數據庫鎖之外的世界提供了一個網關(出入口),這就意味著使用這些對象時,如果不正確的銷毀,那么會對外面的世界代碼麻煩。


但是,遇到下面三種情形時,不要銷毀對象


通過靜態成員或屬性獲取一個共享的對象
如果一個對象的Dispose方法與你的期望不一樣
從設計的角度看,如果一個對象的Dispose方法不必要,且銷毀對象給程序添加了復雜度
第一種情況很少見。多數情形都可以在System.Drawing命名空間下找到:通過靜態成員或屬性獲取的GDI+對象(比如Brushed.Blue)就不能銷毀,這是因為該實現在程序的整個生命周期中都會用到。而通過構造器得到的對象實例,比如new SolidBrush,就應該銷毀,這


同樣適用于通過靜態方法獲取的實例對象(比如Font.FromHdc)。


第二種情況就比較常見。下表以System.IO和System.Data命名空間下類型舉例說明


類型 銷毀功能 何時銷毀
MemoryStream 防止對I/O繼續操作 當你需要再次讀讀或寫流
StreamReader,
StreamWriter 清空reader/writer,并關閉底層的流 當你希望底層流保持打開時(一旦完成,你必須改為調用StreamWriter的Flush方法)
IDbConnection 釋放數據庫連接,并清空連接字符串 如果你需要重新打開數據庫連接,你需要調用Close方法而不是Dispose方法
DataContext
(LINQ to SQL) 防止繼續使用 當你需要延遲評估連接到Context的查詢
第三者情況包含了System.ComponentModel命名空間下的這幾個類:WebClient, StringReader, StringWriter和BackgroundWorker。這些類型有一個共同點,它們之所以是可銷毀的是源于它們的基類,而不是真正的需要進行必要的清理。如果你需要在一個方法中使用這


樣的類型,那么在using語句中實例化它們就可以了。但是,如果實例對象需要持續一段較長的時間,并記錄何時不再使用它們以銷毀它們,就會給程序帶來不惜要的復雜度。在這樣的情況下,那么你就應該忽略銷毀對象。


選擇性地銷毀對象


正因為IDisposable實現類可以使用using語句來實例化,因而這可能很容易導致該實現類的Dispose方法延伸至不必要的行為。比如:


public sealed class HouseManager : IDisposable
{
public void Dispose()
{
CheckTheMail();
}
...
}


想法是該類的使用者可以選擇避免不必要的清理--簡單地說就是不調用Dispose方法。但是,這就需要調用者知道HouseManager類Dispose方法的實現細節。及時是后續添加了必要的清理行為也破壞了規則。


public void Dispose()
{
CheckTheMail(); // Nonessential
LockTheHouse(); // Essential
}
在這種情況下,就應該使用選擇性銷毀模式


public sealed class HouseManager : IDisposable { public readonly bool CheckMailOnDispose; public Demo (bool checkMailOnDispose) { CheckMailOnDispose = checkMailOnDispose; } public void Dispose() { if (CheckMailOnDispose) CheckTheMail(); LockTheHouse(); } ... }


這樣,任何情況下,調用者都可以調用Dispose--上述實現不僅簡單,而且避免了特定的文檔或通過反射查看Dispose的細節。這種模式在.net中也有實現。System.IO.Compression空間下的DeflateStream類中,它的構造器如下

public DeflateStream (Stream stream, CompressionMode mode, bool leaveOpen)
非必要的行為就是在銷毀對象時關閉內在的流(第一個參數)。有時候,你希望內部流保持打開的同時并銷毀DeflateStream以執行必要的銷毀行為(清空bufferred數據)


這種模式看起來簡單,然后直到Framework 4.5,它才從StreamReader和StreamWriter中脫離出來。結果卻是丑陋的:StreamWriter必須暴露另外一個方法(Flush)以執行必要的清理,而不是調用Dispose方法(Framework 4.5在這兩個類上公開一個構造器,以允許你保持


流處于打開狀態)。System.Security.Cryptography命名空間下的CryptoStream類,也遭遇了同樣的問題,當需要保持內部流處于打開時你要調用FlushFinalBlock銷毀對象。


銷毀對象時清除字段


在一般情況下,你不要在對象的Dispose方法中清除該對象的字段。然而,銷毀對象時,應該取消該對象在生命周期內所有訂閱的事件。退訂這些事件避免了接收到非期望的通知--同時也避免了垃圾回收器繼續對該對象保持監視。


設置一個字段用以指明對象是否銷毀,以便在使用者在該對象銷毀后訪問該對象拋出一個ObjectDisposedException,這是非常值得做的。一個好的模式就是使用一個public的制度的屬性:


public bool IsDisposed { get; private set; }
盡管技術上沒有必要,但是在Dispose方法清除一個對象所擁有的事件句柄(把句柄設置為null)也是非常好的一種實踐。這消除了在銷毀對象期間這些事件被觸發的可能性。


偶爾,一個對象擁有高度秘密,比如加密密鑰。在這種情況下,那么在銷毀對象時清除這樣的字段就非常有意義(避免被非授權組件或惡意軟件發現)。System.Security.Cryptography命令空間下的SymmetricAlgorithm類就屬于這種情況,因此在銷毀該對象時,調用


Array.Clear方法以清除加密密鑰。


自動垃圾回收機制


無論一個對象是否需要Dispose方法以實現銷毀對象的邏輯,在某個時刻,該對象在堆上所占用的內存空間必須釋放。這一切都是由CLR通過GC自動處理. 你不需要自己釋放托管內存。我們首先來看下面的代碼


public void Test()
{
byte[] myArray = new byte[1000];
}
當Test方法執行時,在內存的堆上分配1000字節的一個數組;該數組被變量myArray引用,這個變量存儲在變量棧上。當方法退出后,局部變量myArray就失去了存在的范疇,這也意味著沒有引用指向內存堆上的數組。那么該孤立的數組,就非常適合通過垃圾回收機制進


行回收。


垃圾回收機制并不會在一個對象變成孤立的對象之后就立即執行。與大街上的垃圾收集不一樣,.net垃圾回收是定期執行,盡享不是按照一個估計的計劃。CLR決定何時進行垃圾回收,它取決于許多因素,比如,剩余內存,已經分配的內存,上一次垃圾回收的時間。這就


意味著,在一個對象被孤立后到期占用的內存被釋放之間,有一個不確定的時間延遲。該延遲的范圍可以從幾納秒到數天。


垃圾回收和內存占用
垃圾收集試圖在執行垃圾回收的時間與程序的內存占用之間建立一個平衡。因此,程序可以占用比它們實際需要更多的內存,尤其特現在程序創建的大的臨時數組。
你可以通過Windows任務管理器監視某一個進程內存的占用,或者通過編程的方式查詢性能計數器來監視內存占用:
// These types are in System.Diagnostics:
string procName = Process.GetCurrentProcess().ProcessName;
using (PerformanceCounter pc = new PerformanceCounter
("Process", "Private Bytes", procName))
Console.WriteLine (pc.NextValue());
上面的代碼查詢內部工作組,返回你當前程序的內存占用。尤其是,該結果包含了CLR內部釋放,以及把這些資源讓給操作系統以供其他的進程使用。



根就是指保持對象依然處于活著的事物。如果一個對象不再直接或間接地被一個根引用,那么該對象就適合于垃圾回收。


一個跟可以是:


一個正在執行的方法的局部變量或參數(或者調用棧中任意方法的局部變量或參數)
一個靜態變量
存貯在結束隊列中的一個對象
正在執行的代碼可能涉及到一個已經刪除的對象,因此,如果一個實例方法正在執行,那么該實例方法的對象必然按照上述方式被引用。


請注意,一組相互引用的對象的循環被視作無根的引用。換一種方式,也就是說,對象不能通過下面的箭頭指向(引用)而從根獲取,這也就是引用無效,因此這些對象也將被垃圾回收器處理。


image


Finalizers


在一個對象從內存釋放之前,如果對象包含finalizer,那么finalizer開始運行。一個finalizer的聲明類似構造器函數,但是它使用~前綴符號


class Test
{
? ? ~Test()
? ? {
? ? ? ? // finalizer logic ...
? ? }
}


(盡管與構造器的聲明相似,finalizer不能被聲明為public或static,也不能有參數,還不能調用其基類)


Finalizer是可能的,因為垃圾收集工作在不同的時間段。首先,垃圾回收識別沒有使用的對象以刪除該對象。這些待刪除的對象如果沒有Finalizer那么就立即刪除。而那些擁有finalizer的對象會被保持存活并存在放到一個特殊的隊列中。


在這一點上,當你的程序在繼續執行的時候,垃圾收集也是完整的。而Finalizer線程卻在你程序運行時,自動啟動并在另外一個線程中并發執行,收集擁有Finalizer的對象到特殊隊列,然后執行它們的終止方法。在每個對象的finalizer方法執行之前,它依然非?;钴S


--排序行為視作一個跟對象。而一檔這些對象被移除隊列,并且這些對象的fainalizer方法已經執行,那么這些對象就變成孤立的對象,會在下一階段的垃圾回收過程中被回收。


Finalizer非常有用,但它們也有一些限制:


Finalizer減緩內存分配和收集(因為GC需要追蹤那些Finalizer在運行)
Finalizer延長對象及其所引用對象的生命周期(這些對象只有在下一次垃圾回收運行過程中被真正地刪除)
對于一組對象,Finalizer的調用順序是不可預測的
你不能控制一個對象的finalizer何時被調用
如果一個對象的finalizer被阻塞,那么其他對象不能處置(Finalized)
如果程序沒有卸載(unload)干凈,那么finalizer會被忽略
總之,finalizer在一定程度上就好比律師--一旦有訴訟那么你確實需要他們,一般你不想使用他們,除非萬不得已。如果你使用他們,那么你需要100%確保你了解他們會為你做什么。


下面是實施finalizer的一些準則:


確保finalizer快速執行
絕對不要在finalier中使用阻塞
不要引用其他可finalizable對象
不要拋出異常
?
在Finalizer中調用Dispose


一個流行的模式是使finalizer調用Dispose方法。這么做是有意義的,尤其是當清理工作不是緊急的,并且通過調用Dispose加速清理;那么這樣的方式更多是一個優化,而不是一個必須。


下面的代碼展示了該模式是如何實現的


class Test : IDisposable
{
public void Dispose() // NOT virtual
{
Dispose (true);
GC.SuppressFinalize (this); // Prevent finalizer from running.
}
protected virtual void Dispose (bool disposing)
{
if (disposing)
{
// Call Dispose() on other objects owned by this instance.
// You can reference other finalizable objects here.
// ...
}
// Release unmanaged resources owned by (just) this object.
// ...
}
?Test()
{
Dispose (false);
}
}


Dispose方法被重載,并且接收一個bool類型參數。而沒有參數的Dispose方法并沒有被聲明為virtual,只是在該方法內部調用了帶參數的Dispose方法,且傳遞的參數的值為true。


帶參數的Dispose方法包含了真正的處置對象的邏輯,并且它被聲明為protected和virtual。這樣就可以保證其子類可以添加自己的處置邏輯。參數disposing標記意味著它在Dispose方法中被正確的調用,而不是從finalizer的最后采取模式所調用。這也就表明,如果調


用Dispose時,其參數disposing的值如果為false,那么該方法,在一般情況下,都會通過finalizer引用其他對象(因為,這樣的對象可能自己已經被finalized,因此處于不可預料的狀態)。這里面涉及的規則非常多!當disposing參數是false時,在最后采取的模式中


,仍然會執行兩個任務:


釋放對操作系統資源的直接引用(這些引用可能是因為通過P/Invoke調用Win32 API而獲取到)


刪除由構造器創建的臨時文件


為了使這個模式更強大,那么任何會拋出異常的代碼都應包含在一個try/catch代碼塊中;而且任何異常,在理想狀態下,都應該被記錄。此外,這些記錄應當今可能既簡單又強大。


請注意,在無參數的Dispose方法中,我們調用了GC.SuppressFinalize方法,這會使得GC在運行時,阻止finalizer執行。從技術角度講,這沒有必要,因為Dispose方法必然會被重復調用。但是,這么做會改進性能,因為它允許對象(以及它所引用的對象)在單個循環


中被垃圾回收器回收。


復活


假設一個finalizer修改了一個活的對象,使其引用了一個“垂死”對象。那么當下一次垃圾回收發生時,CLR會查看之前垂死的對象是否確實沒有任何引用指向它--從而確定是否對其執行垃圾回收。這是一個高級的場景,該場景被稱作復活(resurrection)。


為了證實這點,假設我們希望創建一個類管理一個臨時文件。當類的實例被回收后,我們希望finalizer刪除臨時文件。這看起來很簡單


復制代碼
public class TempFileRef
{
public readonly string FilePath;
public TempFileRef (string filePath) { FilePath = filePath; }


~TempFileRef() { File.Delete (FilePath); }
}


實際,上訴代碼存在bug,File.Delete可能會拋出一個異常(引用缺少權限,或者文件處于使用中) 。這樣的異常會導致拖垮整個程序(還會阻止其他finalizer執行)。我們可以通過一個空的catch代碼塊來“消化”這個異常,但是這樣我們就不能獲取任何可能發生的錯誤


。 調用其他的錯誤報告API也不是我們所期望的,因為這么做會加重finalizer線程的負擔,并且會妨礙對其他對象進行垃圾回收。 我們期望顯示finalization行為簡單、可靠、并快速。


一個好的解決方法是在一個靜態集合中記錄錯誤信息:


public class TempFileRef
{
static ConcurrentQueue<TempFileRef> _failedDeletions
= new ConcurrentQueue<TempFileRef>();
public readonly string FilePath;
public Exception DeletionError { get; private set; }
public TempFileRef (string filePath) { FilePath = filePath; }
~TempFileRef()
{
try { File.Delete (FilePath); }
catch (Exception ex)
{
DeletionError = ex;
_failedDeletions.Enqueue (this); // Resurrection
}
}
}


把對象插入到靜態隊列_failedDeletions中,使得該對象處于引用狀態,這就確保了它仍然保持活著的狀態,直到該對象最終從隊列中出列。


GC.ReRegisterForFinalize


一個復活對象的finalizer不會再次運行--除非你調用GC.ReRegisterForFinalize


在下面的例子中,我們試圖在一個finalizer中刪除一個臨時文件。但是如果刪除失敗,我們就重新注冊帶對象,以使其在下一次垃圾回收執行過程中被回收。


public class TempFileRef
{
public readonly string FilePath;
int _deleteAttempt;
public TempFileRef (string filePath) { FilePath = filePath; }
~TempFileRef()
{
try { File.Delete (FilePath); }
catch
{
if (_deleteAttempt++ < 3) GC.ReRegisterForFinalize (this);
}
}
}


如果第三次嘗試失敗后,finalizer會靜悄悄地放棄刪除臨時文件。我們可以結合上一個例子增強該行為--換句話說---那就是在第三次失敗后,把該對象加入到_failedDeletions隊列中。


垃圾回收工作原理


標準的CLR使用標記和緊湊的GC對存儲托管堆上的對象執行自動內存管理。GC可被視作一個可被追蹤的垃圾回收器,在這個回收器中,它(GC)不與任何對象接觸;而是被間歇性地被喚醒,然后跟蹤存儲在托管堆對象圖,以確定哪些對象可以被視為垃圾,進而對這些對象


執行垃圾回收。


當(通過new關鍵字)執行內存分配是,或當已經分配的內存達到了某一閥值,亦或當應用程序占用的內存減少時,GC啟動一個垃圾收集。這個過程也可以通過手動調用System.GC.Collect方法啟動。在一個垃圾回收過程中,所有線程都可能被凍結。


GC從根對象引用開始,查找貴根對象對應的整個對象圖,然后把所有的對象標記為可訪問的對象。一旦這個過程完成,所有被標記為不再使用的對象,將被垃圾回收器回收。


沒有finalizer的不再使用的對象立即被處置;而擁有finalizer的不再使用對象將會在GC完成之后,在finalizer線程上排隊以等待處理。這些對象(在finalizer線程上排隊的對象)會在下一次垃圾回收過程中被回收(除非它們又復活了)。


而那些剩余的“活”對象(還需要使用的對象),被移動到堆疊開始位置(壓縮),這樣以騰出更多空間容納更多對象。改壓縮過程有兩個目的:其一是避免了內存碎片,這樣就使得在為新對象分配空間后,GC只需使用簡單的策略即可,因為新的對象總是分配在堆的尾


部。其二就是避免了維護一個非常耗時的內存片段列表任務。


在執行完一次垃圾回收之后,為新對象分配內存空間時,如果沒有足夠的空間可以使用,操作系統不能確保更多的內存使用時,拋出OutOfMemoryException。


優化技術


GC引入了各種優化技術來減少垃圾回收的時間。


通用垃圾回收


最重要的優化就是垃圾回收時通用的。其優點是:盡管快速分配和處置大量對象,某些對象是長存內存,因此他們不需要被垃圾回收追蹤。


基本上,GC把托管堆分為三類:Gen0是在堆上剛剛分配的對象;Gen1經過一次垃圾回收后仍然存活的對象;剩余的為Gen2。


CLR限制Gen0的大小(在32位CLR中,最大16MB,一般大小為數百KB到幾MB)。當Gen0空間耗盡,GC便觸發一個Gen0垃圾回收--該垃圾回收發生非常頻繁。對于Gen1,GC也應用了一個相似的大小限制,因為Gen1垃圾回收也是相當頻繁并且快速完成。Gen2包含了所有類型的


垃圾回收,然而,發生在Gen2的垃圾回收執行時間長,并且也不會經常發生。下圖展示了一個完全垃圾回收:


image


如果真要列出一組大概的數字,那么Gen0垃圾回收執行耗費少于1毫秒,在一個應用程序中一般不會被注意到。而全垃圾回收,如果程序包含大的圖形對象,則可能會耗費100毫秒。執行時間受諸多因素影響二次可能會有不同,尤其是Gen2的垃圾回收,它的尺寸是沒有限


定的。


段時間存活的對象,如果使用GC會非常有效。比如下面示例代碼中的StringBuilder,就會很快地被發生在Gen0上的垃圾回收所回收。


string Foo()
{
var sb1 = new StringBuilder ("test");
sb1.Append ("...");
var sb2 = new StringBuilder ("test");
sb2.Append (sb1.ToString());
return sb2.ToString();
}


大對象堆


GC為大對象(大小超過85,000字節)使用單獨的堆。這就避免了大量消耗Gen0堆。因為在Gen0上沒有大對象,那么就不會出現分配一組16MB的對象(這些對象由大對象組成)之后,馬上觸發垃圾回收。


大對象堆不適合于壓縮,這是因為發生垃圾回收時,移動內存大塊的代價非常高。如果這么做,會帶來下面兩個后果:


內存分配低效,這是因為GC不能總是把對象分配在堆的尾部,它還必須查看中間的空隙,那么這就要求維護一個空白內存塊鏈表。
大對象堆適合于片段化。這意味著凍結一個對象,會在大對象堆上生成一個空洞,這個空洞很難在再被填充。比如,一個空洞留下了86000字節的空間,那么這個空間就只能被一個85000字節或86000自己的對象填充(除非與另外的一個空洞連接在一起,形成更大的空間)
大對象堆還是非通用的堆,大對象堆上的所有對象被視作Gen2


并發回收和后臺回收


GC在執行垃圾回收時,必須釋放(阻塞)你的程序所使用的線程。在這個期間包含了Gen0發生的時間和Gen1發生的時間。


由于執行Gen2回收可能占用較長的時間,因此GC會在你的程序運行時,堆Gen2回收進行特殊的嘗試。該優化技術僅應用于工作站的CLR平臺,一般應用于windows桌面系統(以及所有運行獨立程序的Windows)。原因是由于阻塞線程進行垃圾回收所帶來的延遲對于沒有用戶


接口的服務器應用程序一般不會帶來問題。


這種對于工作站的優化歷史上稱之為并發回收。從CLR4.0kaishi ,它發生了革新并重命名為后臺回收。后臺回收移除了一個限制,由此,并發回收不再是并發的,如果Gen0部分已經執行完而Gen2回收還正在執行。這就意味著,從CLR4.0開始,持續分配內存的應用程序會


更加敏感。


GC通知(適用于服務端CLR)


從Framework 3.5 SP1開始,服務器版本的CLR在一個全GC將要發生時,向你發送通知。你可以在服務器池配置中配置該特性:在一個垃圾回收執行之前,把請求轉向到另外一臺服務器。然后你立即調查垃圾回收,并等待其完成,在垃圾回收執行完成之后,把請求轉回到


當前服務器。


通過調用GC.RegisterForFullGCNotification,可以啟用GC通知。然后,啟動另外一個線程,該線程首先調用GC.WaitForFullGCApproach,當該方法返回GCNotificationStatus指明垃圾回收已經進入等待執行的隊列,那么你就可以把請求轉向到其他的服務器,然后手執


行一次手動垃圾回收(見下節)。然后,你調用GC.WaitForFullGCComplete方法,當該方法返回時,GC完成;那么該服務器就可以開始再次接收請求。然后在有需要的時候,你可以再次執行上述整個過程。


強制垃圾回收


通過調用GC.Collect方法,你可以隨時手動強制執行一次垃圾回收。調用GC.Collect沒有提供任何參數會執行一次完全垃圾回收。如果你提供一個整數類型的參數,那么執行對應的垃圾回收。比如GC.Collect(0)執行Gen0垃圾回收。


// Forces a collection of all generations from 0 through Generation.
//
public static void Collect(int generation) {
? ? Collect(generation, GCCollectionMode.Default)
}




// Garbage Collect all generations.
//
[System.Security.SecuritySafeCritical] ?// auto-generated
public static void Collect() {
? ? //-1 says to GC all generations.
? ? _Collect(-1, (int)InternalGCCollectionMode.Blocking);
}


一般地,允許GC去決定何時執行垃圾回收可以得到最好的性能;這是因為強制垃圾回收會把Gen0的對象不必要地推送到Gen1(Gen1不必要地推送到Gen2),從而影響性能。這還會擾亂GC自身的調優能力--在程序運行時,GC動態地調整每種垃圾回收的臨界值以最大限度地


提高性能。


但是,也有另外。最常見的可以執行手動垃圾回收的場景就是當一個應用程序進入休眠狀態,比如執行日常工作的windows服務。這樣的程序可能使用了System.Timters.Timer以每隔24小時觸發一次行為。當該行為完成之后,在接著的24小時之內沒有任何代碼會執行,那


就意味著,在這段時間內,不會分配任何內存,因此GC就沒有機會被激活。服務在執行時所消耗的任何內存,在接著的24小時都會被持續占用--甚至是空對象圖。那么解決方法就是在日常的行為完成之后調用GC.Collect()方法進行垃圾回收。


為了回收由于finalizer延遲回收的對象,你可以添加一行額外的代碼以調用WaitForPendingFinalizers,然后再調用一次垃圾回收


GC.Collect();
GC.WaitForPendingFinalizers();
GC.Collect();
另外一種調用GC.Collect方法的場景是當你測試一個有Finazlier的類時。
?
內存壓力


.NET運行時基于一些列因素決定何時啟動垃圾回收,其中一個因素就是機器內存的總負載。 如果程序使用了非托管內存,那么運行時會對其內存的使用情況持盲目地樂觀的態度,這是因為CLR之關心托管內存。通過告訴CLR已經分配了特定量的非托管內存內存,來減輕


CLR的盲目性;調用CG.AddMemoryPresure方法可以完成該目的。如果取消該行為(當所占用的托管內存已經被釋放),那么可以調用GC.RemoveMemoryPressure。


管理內存泄漏


在非托管語言中,比如C++,你必須記住當對象不再使用時,應手動地釋放內存;否則,將導致內存泄漏。在托管世界中,內存泄漏這種錯誤時不可能發生的,這歸功于CLR的自動垃圾回收。


盡管如此,大型的和復雜的.NET程序也會出現內存泄漏;只不錯內存泄漏的方式比較溫和,但具有相同的癥狀和結果:在程序的生命周期內,它消耗越來越多的內存,到最后導致程序重啟。好消息是,托管內存泄漏通常容易診斷和預防。


托管內存泄漏是由不再使用的活對象引起,這些對象之所以存活是憑借不再使用引用或者被遺忘的引用。一種常見的例子就是事件處理器--它們堆目標對象保存了一個引用(除非目標是靜態方法)。比如,下面的類:


復制代碼
class Host
{
public event EventHandler Click;
}
class Client
{
Host _host;
public Client (Host host)
{
_host = host;
_host.Click += HostClicked;
}
void HostClicked (object sender, EventArgs e) { ... }
}
復制代碼
下面的測試類包含1個方法實例化了1000個Client對象


復制代碼
class Test
{
static Host _host = new Host();
public static void CreateClients()
{
Client[] clients = Enumerable.Range (0, 1000)
.Select (i => new Client (_host))
.ToArray();
// Do something with clients ...
}
}
復制代碼
你可能會認為,當CeateClients方法結束后,這個1000個Client對象理解適用于垃圾回收。很不幸,每個Client對象都包含一個引用:_host對象,并且該對象的Click事件引用每個Client實例。 如果Click事件不觸發,那么就不會引起注意,或者HostClicked方法不做任


何事情也不會引起注意。


解決這個問題的一種方式就是使Client類實現接口IDisposable,并且在dispose方法中,移除時間處理器


public void Dispose() { _host.Click -= HostClicked; }
Client實例的使用者,在使用完實例之后,調用Client類的dispose方法處置該實例


Array.ForEach (clients, c => c.Dispose());
下面的對比展示兩種方式的差別


CLR Profiler
Index 實現IDisposable 未實現IDisposable
Time line image image
Heap statistics image image
GC Generatation Sizes image image
?
計時器


不要忘記timmers也會引起內存泄漏。根據計時器的種類,會引發兩種不同的內存泄漏。首先我們來看System.Timers命名空間下的計時器。在下面的例子中,Foo類每秒調用一次tmr_Elapsed方法


復制代碼
using System.Timers;
class Foo
{
Timer _timer;
Foo()
{
_timer = new System.Timers.Timer { Interval = 1000 };
_timer.Elapsed += tmr_Elapsed;
_timer.Start();
}
void tmr_Elapsed (object sender, ElapsedEventArgs e) { ... }
}
復制代碼
很不幸,Foo的實例決定不會被回收。原因在于.NET Framework本身持有對計活動的時器的引用,從而導致.net framework會觸發這些計時器的Elapsed事件。因此


.NET Framework將使_timer處于活動狀態
通過tmr_Elapsed事件處理器,_timer將使Foo實現處于活動狀態
當你意識到Timer實現了IDisposable接口之后,解決的方法就在也明顯不過了。處置Timer實例以停止計時器,并確保.NET Framework不再引用該計時器對象。


class Foo : IDisposable
{
...
public void Dispose() { _timer.Dispose(); }
}
相對于我們上面討論的內容,WPF和Windows窗體的計時器表現出完全相同的方式。


然而,System.Threading命名空間下的計時器確是一個特例。.NET Framework沒有引用活動線程計時器;想法,卻直接引用回調代理。這就意味著如果你忘記處置線程計時器,那么finalizer會自動觸發并停止計時器然后處置該計時器。比如:


復制代碼
static void Main()
{
var tmr = new System.Threading.Timer (TimerTick, null, 1000, 1000);
GC.Collect();
System.Threading.Thread.Sleep (10000); // Wait 10 seconds
}
static void TimerTick (object notUsed) { Console.WriteLine ("tick"); }
復制代碼
如果上面的代碼編譯為發布模式,那么計時器會被回收,并且在它再次觸發之前被處置(finalized)。同樣地,我們可以在計時器結束后通過處置該計數器以修復這個問題


using (var tmr = new System.Threading.Timer (TimerTick, null, 1000, 1000))
{
GC.Collect();
System.Threading.Thread.Sleep (10000); // Wait 10 seconds
}
using語句會隱式地調用tmr.Dispose方法,以確保tmr變量確實處于“使用(活動狀態)”;因此不會在代碼塊結束之前被當作是死對象。諷刺的是,調用Dispose方法實際上使對象存活的時間更長了。


診斷內存泄漏


避免托管內存泄漏的最簡單方式就是在編寫應用程序時就添加監控內存占用。你可以在程序中通過調用下面的代碼來獲取當前內存的使用情況


long memoryUsed = GC.GetTotalMemory (true);
如果你采取測試驅動開發,那么你可以使用單元測試判斷是否按照期望釋放了內存。入股這樣的判斷失敗,那么接著你就應該檢查你最近對程序所作的修改。


如果你已經有一個大型程序,并且該程序存在托管內存泄漏問題,那么你應該使用windgb.exe工具來幫助你解決問題。當然你還可以使用其他的圖形化工具,比如CLR Profiler, SciTech的Memory Profiler,或者Red Gate的ANTS Memory Profiler。


弱引用


有時候,引用一個對GC而言是“隱形”的對象,并且對象保持活動狀態,這非常有用。這既是弱引用,它由System.WeakReference類實現。使用WeakReference,使用其構造器函數并傳入目標對象。


var sb = new StringBuilder ("this is a test");
var weak = new WeakReference (sb);
Console.WriteLine (weak.Target); // This is a test
如果目標對象僅僅由一個或多個弱引用所引用,那么GC會把其加入到垃圾回收隊列中。如果目的對象被回收,那么WeakReference的Target屬相則為NULL。


var weak = new WeakReference(new StringBuilder("weak"))
Console.WriteLine(weak.Target); // weak
GC.Collect();
Console.WriteLine(weak.Target == null); // (true)
為了避免目標對象在測試其為null和使用目標對象之間被回收,把目標對象分配給一個局部變量


var weak = new WeakReference (new StringBuilder ("weak"));
var sb = (StringBuilder) weak.Target;
if (sb != null) { /* Do something with sb */ }
一旦目標對象分配給一個局部變量,那么目的對象就有了一個強類型根對象,從而在局部變量使用期間不會被回收。


下面例子中的類通過弱引用追蹤所有被實例化的Widget對象,從而使這些實例不會被回收
class Widget { static List<WeakReference> _allWidgets = new List<WeakReference>(); public readonly string Name; public Widget (string name) { Name = name; _allWidgets.Add (new WeakReference (this)); } public static void ListAllWidgets() { foreach (WeakReference weak in _allWidgets) { Widget w = (Widget)weak.Target; if (w != null) Console.WriteLine (w.Name); } } }
這樣一個系統的唯一缺點就是,靜態列表會隨著時間推移而增加,逐漸累積對應null對象的弱引用。因此,你需要自己實現一些清理策略。

弱引用和緩存

使用弱引用的目的之一是為了緩存大對象圖。通過弱引用,使得耗費內存的數據可以進行簡要的緩存而不是造成內存的大量占用。

_weakCache = new WeakReference (...); // _weakCache is a field
...
var cache = _weakCache.Target;
if (cache == null) { /* Re-create cache & assign it to _weakCache */ }
在實際上,該策略只會發揮一半的作用,這是因為你不能控制GC何時運行,并且也不能控制GC會會執行哪一類回收。尤其是,當你的緩存是在Gen0中,那么這類內存會在微妙級別類被回收。因此,至少,你需要使用兩類緩存,通過它們,首先你擁有一個強類型,然后不

時地把該強類型轉換成弱類型。


弱引用和事件


在前面的章節中,我們看到事件是如何引起內存泄漏。而且解決這種內存泄漏的最簡單方法是避免時間訂閱,或者對為訂閱事件的對象實現Dispose方法。此外,弱引用也提供了另外一種解決方案。


假設一個帶來對其目標持有一個弱引用。那么這樣的一個代理并不會使其目標為活動狀態,除非這些目標對象有獨立的引用。當然,這并不會阻止一個被觸發的代理,在目標對象進入回收隊列之后但在GC開始對該目標對象執行回收前的時間段中,擊中一個未被引用的目


標。為了該方法高效,你的代碼必須非常穩定。下面的代碼就是就是采用這種方式的具體實現:


復制代碼
public class WeakDelegate<TDelegate> where TDelegate : class
{
class MethodTarget
{
public readonly WeakReference Reference;
public readonly MethodInfo Method;
public MethodTarget (Delegate d)
{
Reference = new WeakReference (d.Target);
Method = d.Method;
}
}
List<MethodTarget> _targets = new List<MethodTarget>();
public WeakDelegate()
{
if (!typeof (TDelegate).IsSubclassOf (typeof (Delegate)))
throw new InvalidOperationException
("TDelegate must be a delegate type");
}
public void Combine (TDelegate target)
{
if (target == null) return;
foreach (Delegate d in (target as Delegate).GetInvocationList())
_targets.Add (new MethodTarget (d));
}
public void Remove (TDelegate target)
{
if (target == null) return;
foreach (Delegate d in (target as Delegate).GetInvocationList())
{
MethodTarget mt = _targets.Find (w =>
d.Target.Equals (w.Reference.Target) &&
d.Method.MethodHandle.Equals (w.Method.MethodHandle));
if (mt != null) _targets.Remove (mt);
}
}
public TDelegate Target
{
get
{
var deadRefs = new List<MethodTarget>();
Delegate combinedTarget = null;
foreach (MethodTarget mt in _targets.ToArray())
{
WeakReference target = mt.Reference;
if (target != null && target.IsAlive)
{
var newDelegate = Delegate.CreateDelegate (
typeof (TDelegate), mt.Reference.Target, mt.Method);
combinedTarget = Delegate.Combine (combinedTarget, newDelegate);
}
else
deadRefs.Add (mt);
}
foreach (MethodTarget mt in deadRefs) // Remove dead references
_targets.Remove (mt); // from _targets.
return combinedTarget as TDelegate;
}
set
{
_targets.Clear();
Combine (value);
}
}
}
復制代碼
上述代碼演示了許多C#和CLR的有趣的地方。首先,我們在構造器中檢查了TDelegate是一個代理類型。這是因為C#本身的限制--因為下面的語句不符合C#的語法


... where TDelegate : Delegate // Compiler doesn't allow this
由于必須要進行類型限制,所以我們在構造器中執行運行時檢查。


在Combine方法和Remove方法中,我們執行了引用轉換,通過as運算符(而沒有使用更常見的轉換符)把target對象轉換成Delegate類型。這是由于C#不允許轉換符使用類型參數--因為它不能分清這是一個自定義的轉換還是一個引用抓換(下面的代碼不能拖過編譯)。


foreach(Delegate d in ((Delegate)target).GetInvocationList())
? ? ? ? ? ? ? ? _targets.Add(new MethodTarget(d));
當調用GetInvocationList,由于這些方法可能被一個多播代理調用,多播代理就是一個代理有多余一個的方法接收。


對于Target屬性,我們使其為一個多播代理--通過一個弱引用包含所有的代理引用,從而使其目標對象保持活動。然后我們清楚剩余的死引用,這樣可以避免_targets列表無限制的增長。下面的代碼演示了如何使用我們上面創建的實現了事件的代理類:


復制代碼
public class Foo
{
WeakDelegate<EventHandler> _click = new WeakDelegate<EventHandler>();
public event EventHandler Click
{
add { _click.Combine (value); } remove { _click.Remove (value); }
}
protected virtual void OnClick (EventArgs e)
{
EventHandler target = _click.Target;
if (target != null) target (this, e);
}
}
復制代碼
請注意,在觸發事件時,在檢查和調用之前,我們把_click.Target對象賦值給一個臨時變量。這就避免了目標對象被GC回收的可能性。


參考


http://msdn.microsoft.com/en-US/library/system.idisposable.aspx


========

關于C#中垃圾回收GC雜談

http://blog.csdn.net/pan869823184/article/details/19299581


在初學階段用.Net編寫程序時,一直都未曾考慮過程序垃圾資源回收率的問題,那是因為老師老在課堂講什么不用管,不用理會,一聽到不用理會,好吧,從此寫程序就肆無忌憚的了!程序卡死、內存暴漲、順便偶爾來幾個內存錯誤,一看到這個就頭大了。現在想想,


課堂老師講的那句話,卻只聽進了前半句。。。
閑聊無事,也不用再怕什么在職防止泄露啥啥機密、啥啥技術的、、、嘎嘎、、、、(下面的純屬個人觀點,如有雷同、敬請繞道、、、)
在.Net里面垃圾收集的工作方式:


運行.NET應用程序時,程序創建出來的對象實例都會被CLR跟蹤,CLR都是有記錄哪些對象還會被用到(存在引用關系);哪些對象不會再被用到(不存在引用關系)。CLR會整理不會再被用到的對象,在恰當的時機,按一定的規則銷毀部分對象,釋放出這些對象所占用的


內存。


說到這里,那就引出了新的技術點:


CLR是怎么記錄對象引用關系的?


CLR會把對象關系做成一個“樹圖”,這樣標記他們的引用關系


CLR是怎么釋放對象的內存的?


關鍵的技術是:CLR把沒用的對象轉移到一起去,使內存連續,新分配的對象就在這塊連續的內存上創建,這樣做是為了減少內存碎片。注意!CLR不會移動大對象


垃圾收集器按什么規則收集垃圾對象?


CLR按對象在內存中的存活的時間長短,來收集對象。時間最短的被分配到第0代,最長的被分配到第2代,一共就3代。


一般第0貸的對象都是較小的對象,第2代的對象都是較大的對象,第0代對象GC收集時間最短(毫秒級別),第2代的對象GC收集時間最長。當程序需要內存時(或者程序空閑的時),GC會先收集第0代的對象,


收集完之后發現釋放的內存仍然不夠用,GC就會去收集第1代,第2代對象。(一般情況是按這個順序收集的)


如果GC跑過了,內存空間依然不夠用,那么就拋出了OutOfMemoryException異常。


GC跑過幾次之后,第0代的對象仍然存在,那么CLR會把這些對象移動到第1代,第1代的對象也是這樣。


既然有了垃圾收集器,為什么還要Dispose方法和析構函數?


因為CLR的緣故,GC只能釋放托管資源,不能釋放非托管資源(數據庫鏈接、文件流等)。


那么該如何釋放非托管資源呢?


一般我們會選擇為類實現IDispose接口,寫一個Dispose方法。


讓調用者手動調用這個類的Dispose方法(或者用using語句塊來自動調用Dispose方法)


Dispose執行時,析構函數和垃圾收集器都還沒有開始處理這個對象的釋放工作


有時候,我們不想為一個類型實現Dispose方法,我們想讓他自動的釋放非托管資源。那么就要用到析構函數了。


析構函數是個很奇怪的函數,調用者無法調用對象的析構函數,析構函數是由GC調用的。


你無法預測析構函數何時會被調用,所以盡量不要在這里操作可能被回收的托管資源,析構函數只用來釋放非托管資源


GC釋放包含析構函數的對象,比較麻煩(需要干兩次才能干掉她),


CLR會先讓析構函數執行,再收集它占用的內存。


我們需要手動執行垃圾收集嗎?什么場景下這么做?


GC什么時候執行垃圾收集是一個非常復雜的算法(策略)


大概可以描述成這樣:


如果GC發現上一次收集了很多對象,釋放了很大的內存,


那么它就會盡快執行第二次回收,


如果它頻繁的回收,但釋放的內存不多,


那么它就會減慢回收的頻率。


所以,盡量不要調用GC.Collect()這樣會破壞GC現有的執行策略。


除非你對你的應用程序內存使用情況非常了解,你知道何時會產生大量的垃圾,那么你可以手動干預垃圾收集器的工作?


我有一個大對象,我擔心GC要過很久才會收集他,


[csharp] view plain copy print?在CODE上查看代碼片派生到我的代碼片
??
關于弱引用和垃圾收集之間的關系?


當一個大對象被使用后不存在引用關系時,GC就會自動回收它占用的內存。


當這個對象足夠大的情況下,GC在回收它時,可能時間稍微會長點,當用戶需要再次使用該對象時,我們可以從回收池中再次提取該對象,這里就涉及到弱引用,代碼如下:




[csharp] view plain copy print?在CODE上查看代碼片派生到我的代碼片
var bss = new BsCtl(BrowserContainer); ?
? ? ? ? ? ? var vbss = new WeakReference<BsCtl>(bss); ?
? ? ? ? ? ? bss = null; ?
? ? ? ? ? ? BsCtl ok; ? ? ? ? ? ? ?
? ? ? ? ? ? vbss.TryGetTarget(out ok); ?
? ? ? ? ? ? //如果沒有進行垃圾收集OK不會為NULL ?
? ? ? ? ? ? if (ok == null) ?
? ? ? ? ? ? { ?
? ? ? ? ? ? ? ? //如果已經進行了垃圾收集,就會執行這段代碼 ?
? ? ? ? ? ? ? ? ok = new BsCtl(BrowserContainer); ?
? ? ? ? ? ? } ?




垃圾收集隨時可以收集bss對象,


如果收集了,就會進入if語句塊,如果沒有收集,就不會進入if語句塊,TryGetTarget(out ok)就成功把bss從垃圾堆里撈回來了。


注意:這里只說了短弱引用,沒有提及長弱引用,我覺得長弱引用使用的場景較少。


垃圾收集器優點:


因為我沒有很豐富的C/C++編程經驗,如果想談垃圾收集器的好處,那么勢必要和C/C++這樣的較低級的語言對比。所以一般性的回答都是減少內存使用不當的BUG,提升編程效率之類的問題。
========

垃圾收集器原理

http://www.tuicool.com/articles/Nbyqi2
原文 ?http://www.cnblogs.com/izhaogang/p/collector.html


在編程的過程中,你是否遇到過OutOfMemeryException的異常?程序在做性能測試時,應用服務器程序消耗的內存不斷上升?在使用開源框架時,由于沒有及時的Dispose而導致程序的異常發生?而造成這些異常的原因都是沒有合理的釋放內存導致的。我們不經要問,C#


框架下不是有GC(自動垃圾收集器)嗎?那么為什么還會出現如此異常錯誤呢?GC到底何時執行,執行時又做了什么?GC對性能的影響?怎樣合理的釋放資源呢?下面我們來揭開垃圾收集器的神秘面紗。


1、垃圾收集平臺的基本工作原理


1.1 基本原理分析


我們知道,C#是CLR(Common Language Runtime公共語言運行庫)下的一種托管代碼語言,它的類型和對象在應用計算機內存時,大體用到兩種內存,一種叫堆棧,另一種叫托管堆。C#中主要分為值類型和引用類型,當聲明一個值類型對象時,會在棧中分配適當大小的


內存,內存空間存儲對象的值。其中維護一個棧指針,它包含棧中下一個可用內存空間的地址。當一個變量離開作用域時,棧指針向下移動并釋放變量所占用的內存,所以它任然指向下一個可用地址;當聲明一個引用類型對象時,引用變量也利用棧,但這時棧包含的只是


對另一個內存位置的引用,而不是實際的值。這個位置是托管堆中的一個地址,和棧一樣,它也維護一個指針,包含堆中下一個可用內存空間的地址。我們來寫一個簡單的事例代碼,看看它內部到底發生了什么?

namespace SourceDemo {class Program{ static void Main(string[] args){int iTotal = 1;Order order = new Order();}}class Order{} }

通過ILDASM.EXE工具查看對應的IL代碼如下:

.method private hidebysig static void Main(string[] args) cil managed {.entrypoint // Code size 10 (0xa).maxstack 1 .locals init ([0] int32 iTotal,[1] class SourceDemo.Order order)IL_0000: nopIL_0001: ldc.i4.1IL_0002: stloc.0IL_0003: newobj instance void SourceDemo.Order::.ctor()IL_0008: stloc.1IL_0009: ret } // end of method Program::Main

可以看到,聲明引用類型和值類型的區別在于引用類型有一個newObj創建對象的操作。那么newObj到底做了哪些操作呢?主要操作如下:


計算新建對象所需要的內存總數(包括基類的所有字段字節總數)。
在前面所得字節總數的基礎上再加上對象開銷所需的字節數。開銷包括:類型對象指針和同步塊的索引。
CLR檢查保留區域是否有足夠的空間來存放新建對象。


如果空間足夠,調用類型的構造函數,將對象存放在NextObjPtr指向的內存地址中。
如果空間不夠,就執行一次垃圾回收來清理托管堆,如果依然不夠,則拋出OutOfMemeryException異常
最后,移動NextObjPtr指向托管堆下一個可用地址。可以看到,垃圾收集器通過檢查托管堆上不再使用的對象來回收內存,那么垃圾收集器怎么確定對象是不再使用的對象呢?請接著往下看。


1.2 應用程序的根


每個應用程序都有一組根,一個根就是一個存儲對象,其中包含一個指向引用類型的內存指針,它或者指向托管堆的對象,或者被設為null。如類字段、方法參數或者是局部變量都是根,注意只有引用類型才被認為是根,而值類型只是占用內存永遠不會被認為為根。垃


圾收集器是怎么工作的呢?工作主要分為以下兩階段:


第一階段,標記對象階段。?
垃圾收集器開始執行的時候,首先假設托管堆中的對象都是可以收集的垃圾。它開始遍歷線程的堆棧檢查所有的根,如果發現根引用了一個對象那么就在該對象的同步塊的索引字段上設置一位來標記它。同時檢查該對象是否引用其他對象,如果引用則進行標記,通過遞


歸的方式進行標記,直到發現根及根引用的對象已經標記,垃圾收集器將繼續收集下一個根。
第二階段,壓縮階段。該階段垃圾收集器線性的遍歷堆以尋找包含未標記對象的連續區塊。如果垃圾收集器找到了較小內存塊,那么它忽略內存不計;如果找到了較大的連續內存塊,那么垃圾收集器將把內存中非垃圾對象搬移到這些連續內存塊中以壓縮托管堆。


圖:垃圾收集器執行前的托管堆。


對于以上描述,專業詞匯較多不是蠻好理解。我們來舉一個容易理解的例子:有一個執行清理房間的任務(任務方法),房間中有很多物品、柜子盒子及其里面的物品等都需要清理(對象清理),當我們執行這個任務時(調用方法),清理過程中我們可以標記物品,同


時可能存在這樣的情況,我們在清理其中一個盒子的時候,發現盒子里面還有其他的盒子,如手機盒子里面還有個裝充電器的盒子(手機里面又引用了手機充電器的對象),那么我們需要深度遍歷清理標記所有的盒子,遍歷完成后,我們會發現,有很多以前有用現在無


用的東西,如老式的手機充電器、數據線等;廢舊的電池等(不在使用,不可達對象);這樣我們會根據當時的情況將不再使用對象進行清理處理。而垃圾清理器大概就是做這樣的工作,只是它處理的方式及細節更加復雜。


1.3 對象的代


當CLR試圖尋找不可達對象的時候,它需要遍歷托管堆上的對象。隨著程序的運行,托管堆上的對象也越來越多,如果要對整個托管堆進行垃圾回收,那么會嚴重的影響性能。為了優化這個過程,CLR中使用了"代"的概念,托管堆上的每一個對象都被指定屬于某個“代”


(generation)。


托管堆上的對象可以分為0、1、2三個代:


0代:新構建的對象,垃圾收集器還沒對它們執行任何檢查
1代:在一次垃圾收集清理沒有被回收的對象
2代:在至少兩次垃圾收集清理沒有被回收的對象。
下面我們來看看CLR如何通過這種機制來優化垃圾收集機制的性能?


圖:垃圾收集代策略執行過程


CLR初始化時,它會為每一代選擇一個預算容量,假設為0代為256KB,1代為2M,2代為10M(實際可能不同),如果分配的新對象導致代容量超過預算容量,那么將執行垃圾收集清理操作。如上圖所示:


1、垃圾回收前,托管堆中對象ABCDE都處于第0代;
2、假設ABCDE已占用256K內存,當需要創建新對象F時,開始執行垃圾回收,垃圾收集器判斷CE為不可達對象,將對他們進行清理,完成后,對象ABD將變為1代對象;
3、現在需創建FGHIJ對象,它們將都處于0代;這個時候1代對象中的B可能不再被調用變為不可達對象。這里面會發現:當0代對象內存不超過256KB時,垃圾回收器不會對1代對象進行檢查清理,因此1代中不可達對象B在垃圾清理后依舊會保留在內存中。那么什么時候B會


被清理呢?
4、創建新對象,發現1代空間操作預算容量2M,這個時候將引發垃圾收集,回收不可達對象BH,同時原有1代對象AD變為2代,0代對象FGIJ變為1代。
下面我們來通過事例代碼驗證上述的執行步驟:


internal sealed class GenObj {
? ? ~GenObj()
? ? {
Console.WriteLine("Finalize GenObj");
? ? }
}
class Program
{
? ? static void Main(string[] args)
? ? {
Console.WriteLine("Maxnum gen:" + GC.MaxGeneration);
//創建一個新的對象
object o = new GenObj();
//因為是新創建的對象,為0代
Console.WriteLine("Gen "+GC.GetGeneration(o));
//執行垃圾收集提升對象的代
GC.Collect();
Console.WriteLine("Gen " + GC.GetGeneration(o));
//這里強制回收
GC.Collect();
Console.WriteLine("Gen " + GC.GetGeneration(o));
GC.Collect();
Console.WriteLine("Gen " + GC.GetGeneration(o));
o = null;
Console.WriteLine("Collecting Gen 0");
GC.Collect(0);
GC.WaitForPendingFinalizers();
Console.WriteLine("Collecting Gen 0 1");
GC.Collect(1);
GC.WaitForPendingFinalizers();
Console.WriteLine("Collecting Gen 0 1 2");
GC.Collect(2);
GC.WaitForPendingFinalizers();
Console.ReadLine();
? ? } ?
}
程序的返回結果為:
Maxnum gen: 2
Gen 0
Gen 1
Gen 2
Gen 2
Collecting Gen 0
Collecting Gen 0 1
Collecting Gen 0 1 2
Finalize GenObj
這里需要注意的時:
GC.Collect() ?強制對所有代碼進行即時回收
GC.Collect(int Generation) 強制對0代到指定代對象進行回收
因此:我們將代碼第二處的GC.Collect()修改為:GC.Collect(0)?
程序的返回結果則變為:
Maxnum gen: 2
Gen 0
Gen 1
Gen 1 ? ? //注意這里變為1 而不是2
Gen 2
Collecting Gen 0
Collecting Gen 0 1
Collecting Gen 0 1 2
Finalize GenObj
由此可以看出,垃圾回收機制通過引入代的機制,由遍歷整個托管堆對象變成遍歷少量的對象來達到性能優化的目的。當然,不僅如此,它還有其他的策略來進行性能優化。


策略1:根據回收存貨的比例高低來調整預算容量。如果垃圾收集器發現0代對象被收集以后存活下來的對象很少,它可能會決定將第0代的預算容量從256K減少到128K。已分配空間的減少意味著垃圾收集器執行的頻率更高,但每次收集工作會減少,這樣一來進程的工作集


會變小;如果發現0代對象被手機以后存貨下來的對象很多,也就是說沒有回收較多的內存,那么可能決定將預算容量從256K增加到512K,這樣回收的頻率降低,執行回收的內存較多。

策略2:大對象回收特殊機制。大對象是指任何占用內存等于或超過85000字節的對象,將會總被認為為2代對象。原因是:該堆中的對象的終結和內存釋放和小對象相同,但是它永遠不會被壓縮。因為將85000字節的內存塊搬移到堆中要浪費很多的CPU時間。


對于這樣的場景,我們來舉一個更易懂的例子,一個公司業績下滑,需要通過裁員來減清負擔,開始時決定全公司范圍裁員,結果搞的人心惶惶,人人自危,極大的影響了員工士氣和工作效益(就好比遍歷整個堆棧導致性能不佳);然后公司管理層決定優化這個方案,

將裁員的人員定為剛進公司1年的新員工(0代),因為這樣有一定的好處,不僅人少執行效率快,賠的錢少而且對業務影響也較小;經過這次風波后(資源清理),隨著市場行情的提升,業績越來越好,結果又持續招人(新對象創建),但是過了1年,由于XXX原因,效

益大幅下降(內存、性能等下降),又要開始裁員(引發系統清理),規則還是按照上一次的規則,只是之前上一年沒有裁掉的新員工(0代),他們在今年不再是一年級的新員工(上升為1代),在裁員的時候,發現只是裁新員工(部分表現不佳的)還不夠,那么需要


對去年新員工(1代)表現差的進行裁員(0代超過預算容量則開始檢查1代)。這個例子可能不是很符合現實,但是它可以體現出代的思想。


1.4 小結及啟發


通過上面的介紹,我們來回顧總結一下。我們可以學習到什么?我們大概能知道垃圾收集器是如何工作的,是如何高性能的工作的。我們不僅要會使用它,我們還需要知道它的原理是什么,這樣當你遇到它,你就不會覺得它有多么的神秘,不僅如此,更重要的是,里面


有很多思想是我們可以借鑒的,因為這些思想都是行內權威人士智慧的結晶。通過了解,我們還可以舉一反三學習到:


程序中根的標記遞歸算法,這不正是深度優先的算法嗎?這個算法在很多場景都在使用,比如說搜索中的爬蟲程序、圖的遍歷、最優最快路徑等等應用場景都會用到;垃圾收集器通過引進“代”的概念來進行性能優化的策略原理。我們在項目的開發過程中,也有很多應

用場景都可以借鑒這種思路來進行性能優化。比如說:現在很多大并發場景如12306、秒殺、購物網站等使用的排隊機制,它們可以智能的設置隊列容量,這不正是很好的體現嗎?在比如說多級緩存系統系統緩存策略等等,這些應用場景都可以借鑒該思想。

2、資源清理Finalize、Dispose、Using用法說明

2.1 Finalize使用及原理說明


終結(Finalization)是CLR提供的一種機制,他允許對象在垃圾回收其內存之前執行一些清理工作,回收它占用的資源(內存、本地資源等),當垃圾收集器判定一個對象為可收集垃圾時,它會通過該對象的Finalize方法來執行清理。C#中是通過在類名稱前加一個波浪


線~來定義的,這也就是我們所說的析構函數。通過ILDASM.EXE工具查看上面跟部分的GenObj類,打開確實可以發現Finalze方法。那么我們來看看Finalize的工作原理是什么?


.method family hidebysig virtual instance void?
? ? Finalize() cil managed
{
// Code size 25 (0x19)


.maxstack 1

.try

{

IL_0000: nop

IL_0001: ldstr "Finalize GenObj"

IL_0006: call void [mscorlib]System.Console::WriteLine(string)

IL_000b: nop

IL_000c: nop
IL_000d: leave.s IL_0017

} // end .try

finally


{


IL_000f: ldarg.0


IL_0010: call instance void [mscorlib]System.Object::Finalize()


IL_0015: nop


IL_0016: endfinally


} // end handler


IL_0017: nop


IL_0018: ret


} // end of method GenObj::Finalize


可以看到方法體的代碼在Try中生成,而base.Finalize的調用則在finally中。通常Finalize方法的實現時調用Win32的CloseHandle函數,該函數接受本地資源的句柄作為參數。如:FileStream類定義了一個文件句柄字段來標示本地資源,同時也定了一個Finalize方法,


該方法內部調用CloseHandler函數并為它傳遞文件句柄作為參數,確保托管堆的FileStream對象成為可收集垃圾之前,本地文件句柄可以得到關閉。C#中也提供給了相應的類來進行非托管資源的清理類:


CriticalFinalizerObject類型。
它位于命名空間System.Runtime.ConstrainedExecution。CLR賦予它三個很酷的特征:1、首次構造派生于它的類型的任何對象,CLR立即對繼承的層次結構中的所有Finalize方法進行JIT編譯,這樣在內存較小的情況下,不會影響Finalize方法因為沒有內存而無法執行,

從而導致資源泄露。2、CLR在調用了非派生自CriticalFinalizerObject該類的Finalize方法后再調用派生于CriticalFinalizerObject類型的對象的Finalize方法。這樣可以確保擁有Finalize方法的托管資源類可以在Finalize方法中訪問派生自CriticalFinalizerObject

的對象。3、應用程序域被非法中斷時,可以確保CLR調用派生自CriticalFinalizerObject類型的Finalize方法來執行資源清理。

SafeHandle類型及其派生類型。
Microsoft意識到最常用的本地資源就是有Windows提供的資源,而且Windows資源都是由句柄操作。為了使便車簡單,因此提供了SafeHandle類來提供資源句柄操作,它位于命名空間System.Runtime.InteropService.它本身派生于對于CriticalFinalizerObject類型,對


于這個類的用法,具體可以查閱相關資料。


我們來看看SafeHandle類都作了什么?


[SecurityCritical, __DynamicallyInvokable, SecurityPermissio(SecurityAction.InheritanceDemand, UnmanagedCode=true)]
public abstract class SafeHandle : CriticalFinalizerObject, IDisposable
{
// Fields
private bool _fullyInitialized;
private bool _ownsHandle;
private int _state;
[ForceTokenStabilization]
protected IntPtr handle;
// Methods
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail)]
protected SafeHandle(IntPtr invalidHandleValue, bool ownsHandle)
{
this.handle = invalidHandleValue;
this._state = 4;
this._ownsHandle = ownsHandle;
if (!ownsHandle)
{
GC.SuppressFinalize(this);
}
this._fullyInitialized = true;
}
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success), SecurityCritical, TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
public void Close()
{
this.Dispose(true);
}
[MethodImpl(MethodImplOptions.InternalCall), ReliabilityContract(Consistency.WillNotCorruptState, Cer.MayFail), SecurityCritical, __DynamicallyInvokable]
public extern void DangerousAddRef(ref bool success);
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success), TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
public IntPtr DangerousGetHandle()
{
return this.handle;
}
[MethodImpl(MethodImplOptions.InternalCall), SecurityCritical, ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success), __DynamicallyInvokable]
public extern void DangerousRelease();
[SecuritySafeCritical, ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success), __DynamicallyInvokable, TargetedPatchingOptOut("Performance critical to inline this type of method across NGen image boundaries")]
public void Dispose()
{
this.Dispose(true);
}
[SecurityCritical, ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success), __DynamicallyInvokable]
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
this.InternalDispose();
}
else
{
this.InternalFinalize();
}
}
[SecuritySafeCritical, __DynamicallyInvokable]
~SafeHandle()
{
this.Dispose(false);
}
[MethodImpl(MethodImplOptions.InternalCall), ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
private extern void InternalDispose();
[MethodImpl(MethodImplOptions.InternalCall), ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success)]
private extern void InternalFinalize();
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success), __DynamicallyInvokable]
protected abstract bool ReleaseHandle();
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success), TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries")]
protected void SetHandle(IntPtr handle)
{
this.handle = handle;
}
[MethodImpl(MethodImplOptions.InternalCall), SecurityCritical, ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success), __DynamicallyInvokable]
public extern void SetHandleAsInvalid();
// Properties
[__DynamicallyInvokable]
public bool IsClosed
{
[ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success), TargetedPatchingOptOut("Performance critical to inline across NGen image boundaries"), __DynamicallyInvokable]
get
{
return ((this._state & 1) == 1);
}
}
[__DynamicallyInvokable]
public abstract bool IsInvalid { [ReliabilityContract(Consistency.WillNotCorruptState, Cer.Success), __DynamicallyInvokable] get; }
}
首先可以看到,它繼承于CriticalFinalizerObject對象,這樣讓它具備上面提到的三個特性;它同時實現了IDisposable接口。然后通過Dispose和close釋放托管資源和非托管資源。其中提供了對本地資源句柄的操作,ReleaseHandle 如果在派生類中重寫,執行釋放句


柄所需的代碼。更多細節可以查看, https://msdn.microsoft.com/zh-cn/library/system.runtime.interopservices.safehandle.aspx


哪些時間會導致Finalize方法的調用呢?


0代對象充滿 該事件是目前導致垃圾回收執行最常見的一種方式。
代碼顯式調用GC.Collect()方法 Micrsoft強烈建議不要這樣干,但某些時候執行還是有意義的。
Windows報告內存不足
CLR卸載應用程序域
CLR被關閉
由此可以看出Finalize方法的執行不能顯式調用,因此它執行時間具備不確定性。

2.2 Dispose使用

Finalize方法非常有用,它可以確保托管對象在釋放內存的同時不會泄露本地資源,但是它的問題在于我們不知道何時才會調用它。在使用本地資源的托管類型時,能夠確定的釋放或者是關閉對象都是很有用的。要提供確定釋放或者關閉對象的能力,一個類型通常需要

實現一種釋放模式(DisposePattern).通過前面的SafeHandler類可以顯式關閉本地資源,這是由于它實現了IDisposable接口。我們來看一下MSDN給出的Dispose釋放寫法。


using System;


class BaseClass : IDisposable
{
//Flag: Has Dispose already been called?bool disposed = false;


// Public implementation of Dispose pattern callable by consumers.


public void Dispose()


{


Dispose(true);


//調用GC.SuppressFinalize(this)方法來阻止Finalize方法的調用


GC.SuppressFinalize(this);


}


// Protected implementation of Dispose pattern.
protected virtual void Dispose(bool disposing)
{
if (disposed)
return;?
if (disposing) {
// 釋放托管資源
//
}
// 釋放非托管資源
//設置true 表示對象正在被顯式的執行資源清理而不是垃圾收集器執行終結操作
disposed = true;
}
}
通過Dispose來釋放資源,其實只是清理SafeHandle對象包裝的資源方式之一。SafeHandle包裝的資源清理還可以通過編程人員顯式的調用Close、Dispose方法來清理;或者是通過垃圾收集器調用對象的Finalize方法來釋放。上面給出的SafeHandle類代碼實現,正好可以


說明這一點。


2.3 Using使用


前面介紹了怎樣顯示的調用一個類型的Dispose或者是Close方法,如果決定顯式調用,那么強烈建議把他們放在一個異常處理的finally代碼塊中,這樣可以保證它們被執行。但是這樣做書寫的代碼很是繁瑣。為了解決這個問題,C#提供了一個using語句,它簡化了上述

finally的操作,并且能夠得到和上述一樣的效果。

3、實例分析

3.1 Windows服務關閉問題


在很多時候,我們需要編寫并開啟一個Windows服務來執行需要循環執行的應用需求,在開啟任務后,程序順利執行;當關閉Windows服務時,發現服務關閉了,但是服務對應的資源線程還沒有完全結束,要經過一段時間后,服務才會完全停止。這很有可能是因為,在服


務Stop()方法里面,沒有完全釋放程序調用的資源導致的。


3.2 Redis使用遇到的問題


記得以前在使用Redis過程中遇到了一個奇怪的問題。


先附上Redis幫助類:RedisManager.cs


internal class RedisManager
{
private static readonly PooledRedisClientManager _Manager;
static RedisManager()
{
_Manager = GetManager();
}
public static PooledRedisClientManager Manager
{
get
{
return _Manager;
}
}
#region Help Methods
private static PooledRedisClientManager GetManager()
{
var conn = ConfigurationManager.ConnectionStrings["Redis"].ConnectionString;
if (string.IsNullOrEmpty(conn))
{
throw new Exception("請配置ConnectionString Key 為Redis的連接串");
}
var manager = new PooledRedisClientManager(conn);
return manager;
}
#endregion
}
Dao.cs 數據操作基類


public abstract class Dao<TEntity> : IDisposable where TEntity : class
{
private IRedisClient _Client;
private IRedisTypedClient<TEntity> _Collection;
public Dao()
{
_Client = RedisManager.Manager.GetClient();
_Collection = _Client.As<TEntity>();
}
public void Save(TEntity entity)
{
_Collection.Store(entity);
}
public TEntity Get(object id)
{
return _Collection.GetById(id);
}
public void Delete(Object id)
{
_Collection.DeleteById(id);
}
#region Dispose
~Dao()
{
_Client.Dispose();
}
/****以下為修改BUG時新加****/
/*public void Close()
{
_Client.Dispose();
}
public void Dispose()
{
_Client.Dispose();
}*/
#endregion
}
單元測試用例:


[TestMethod]
public void TestAddAndGet()
{
for (var i = 0; i < 10; i++)
{
//Bug前代碼
dao.Save(new TestEntity() { Id = "fdsafsa", FirstName = "Jack", SecondName = "Cui" });
Assert.AreEqual(dao.Get("fdsafsa").FirstName, "Jack");
//修復Bug代碼
/*using (var dao = new TestDao())
{
dao.Save(new TestEntity() { Id = "fdsafsa", FirstName = "Jack", SecondName = "Cui" });
Assert.AreEqual(dao.Get("fdsafsa").FirstName, "Jack");
}*/
}
}
運行單元測試,單條保存測試用例通過。但是在應用程序大量數據操作測試的時候,發現寫入Redis的數據有丟失的情況,但并不是每次都會丟失。并且系統沒有操作失敗的異常日志。這個時候就感覺特別奇怪,于是就在單元測試時想辦法重現這個錯誤,當按上面測試用


例,循環10次保存數據測試用例通過,當循環100次時,發現異常重現了。沒有異常拋出,測試用例也沒有返回。然后設置斷點調試,發現在運行第11次時,系統在_Client = RedisManager.Manager.GetClient()此處停住了??戳艘幌?#xff0c;代碼中用到了PooledRedis?


ClientManager 客戶端池對象,池對象有個特點是,有一個池的容量,當容量滿的時候需要等待。而現在池中保存的就是RedisClient,是否是由于RedisClient達到了使用上限導致的。那么我們手動釋放一下RedisClient是否解決這個錯誤,馬上嘗試了一下,通過使用


Using顯式釋放資源,發現確實解決了問題。問題是解決了,但是我們不經要問?系統中不是有析構函數嗎?難道這是PooledRedisClientManager池的一個Bug嗎?帶著這樣的疑問,讓我們來查看一下問題到底出現在哪里?


1、析構函數只有在GC進行垃圾收集時才會被調用,而GC并不會馬上執行,執行時間是不確定的。


2、那么這到底是不是PooledRedisClientManager池的一個Bug呢?


查看了一下對應的源碼:


protected readonly int PoolSizeMultiplier = 10;
public IRedisClient GetClient()
{
lock (writeClients)
{
AssertValidReadWritePool();
RedisClient inActiveClient;
while ((inActiveClient = GetInActiveWriteClient()) == null)
{
if (PoolTimeout.HasValue)
{
// wait for a connection, cry out if made to wait too long
if (!Monitor.Wait(writeClients, PoolTimeout.Value))
throw new TimeoutException(PoolTimeoutError);
}
else
Monitor.Wait(writeClients, RecheckPoolAfterMs);
}
WritePoolIndex++;
inActiveClient.Active = true;
InitClient(inActiveClient);
return inActiveClient;
}
}
從源代碼可以看出,在獲取可用GetInActiveWriteClient()為null時,有一個循環調用,線程一直等待獲取可以用的RedisClient.當池中無可用的RedisClient對象時,那么線程將一直等待。對象池有一個特征:獲取池中對象 → 使用對象 → 歸還對象 。那么是否是由


于使用完對象后沒有歸還對象呢?通過Using釋放使用的對象切實可以起到歸還的效果。于是再去挖掘程序中是否有Dispose或者是歸還對象的操作, 發現該池定義了protected void Dispose(RedisClient redisClient)的方法,但是瀏覽源碼切實沒有發現任何地方顯式


調用這個Dispose。


3.3 應用程序線程使用內存不斷上升


記得之前同事遇到這樣的一個BUG,系統上線后,監控發現該應用程序使用內存不斷上升,這個不得了,這意外著隨著時間的持續,系統會因為內存不足導致應用掛掉。于是通過獲取線上的DUMP文件,通過分析,發現char[] 數組的對象特別多,那么在什么時候我們會使


用這么多的char[]呢?回顧一下,好像沒有直接使用char[]的地方,但是我們知道,string對象經過編譯后,它就是有char[]組成的,我們試著去找是否有StringBulider對象不停地加入數據,但是沒有執行清理。結果真的發現有如此一個對象,這個對象據說是用來進行


測試調試使用的,上線的時候應該去掉,結果上線的時候忘記了。


參考資料


《框架設計 CLR Via C#》 Jeffrey Richter著


結束語:


在技術學習的過程中,很多時候我們知其然不知其所以然,因此在開發的過程中可能遇到不知其所以然而導致的問題,到最后也無法找到問題的根本原因。我們需要深入了解原理,并且通過原理舉一反三,在其他類似的應用場景可以借鑒他們的思想。


寫此文主要有三方面的目的:


1、將學過的東西通過文字的形式分享出來,一直被分享,從未進行分享。- -


2、有些時候,很多東西我們可能都理解,但是很難系統的書寫出來,書寫出來可以對已學知識和個人理解做一個記錄和總結,進一步鞏固已學知識。


3、試著將比較枯燥的概念和理論通過更通俗易懂的例子解釋出來,同時能夠將這些枯燥難解的理論和實際結合,讓知識體現的更加具體一點。


個人感覺,文章還沒有達到個人預期效果。其主要表現在如下兩方面:其一,對于細節的理解可能說的不夠透徹,沒有找到通俗易懂的例子來進行解釋;其二,對于項目中遇到的關于垃圾收集典型問題所舉例子還不夠豐富,沒有真正體現出核心的價值。因此歡迎各位博


友能夠分享個人經驗進行補充,讓對此方面知識還不是十分了解的同學更容易理解。

========

淺談.NET垃圾回收機制

? ? ? ? 垃圾收集器(GarbageCollection)是組成.Net平臺一個很重要的部分,.NET垃圾回收機制降低了編程復雜度,使程序員不必分散精力去處理析構。不妨礙設計師進行系統抽象。減少了由于內存運用不當產生的Bug。成功的將內存管理工作從程序的編寫時,脫離至


運行時的優點。


方法/步驟
1
?關于垃圾回收
?
? ? ? 在.NET Framework中,內存中的資源(即所有二進制信息的集合)分為"托管資源"和"非托管資源".托管資源必須接受.NET Framework的CLR(通用語言運行時)的管理(諸如內存類型安全性檢查),而非托管資源則不必接受.NET Framework的CLR管理. 需要手動清理垃圾(


顯式釋放)。
?
? ? ? 托管資源在.NET Framework中又分別存放在兩種地方: "堆棧"和"托管堆"(以下簡稱"堆");規則是,所有的值類型(包括引用和對象實例)和引用類型的引用都存放在"堆棧"中,而所有引用所代表的對象實例都保存在堆中。在C#中,釋放托管資源是可以自動通過"垃圾回


收器"完成的(注意,"垃圾回收"機制是.NET Framework的特性,而不是C#的).
?
? ? ? 在C++時代,我們需要自己來管理申請內存和釋放內存. 于是有了new, delete關鍵字. 還有的一些內存申請和釋放函數(malloc/free). C++程序必須很好地管理自己的內存, 不然就會造成內存泄漏(Memory leak). 在.net時代, 微軟為開發人員提供了一個強有力的


機制--垃圾回收. 垃圾回收機制是CLR的一部分, 我們不用操心內存何時釋放, 我們可以花更多精力關注應用程序的業務邏輯. CLR里面的垃圾回收機制用一定的算法判斷某些內存程序不再使用,回收這些內存并交給我們的程序再使用.
2
?垃圾回收的功能
?
? ? ?1、用來管理托管資源和非托管資源所占用的內存分配和釋放。
?
? ? ?2、尋找不再使用的對象,釋放其占用的內存, 以及釋放非托管資源所占用的內存。
?
? ? ?3、垃圾回收器釋放內存之后, 出現了內存碎片, 垃圾回收器移動一些對象, 以得到整塊的內存,同時所有的對象引用都將被調整為指向對象新的存儲位置。
3
?回收內存的模式
?
? ? ?在.net中提供三種模式來回收內存資源:dispose模式,finalize方法,close方法。
?
? ? ?1、dispose提供了一種顯示釋放內存資源的方法。dispose調用方法是:要釋放的資源對象.dispose().
?
? ? ?2、finalize方法是.net的內部的一個釋放內存資源的方法。這個方法不對外公開,由垃圾回收器自己調用。
?
? ? ?3、close和dispose其實一樣,只不過有的對象沒有提供dispose的方法,只提供了close方法,而close其實在那個對象的類中,依然是調用了一個私有的dispose方法,而finalize其實也是調用一個不對外公開的dispose方法。
4
?回收一般過程
?
? ? ?1、垃圾回收時機:托管堆滿了,內存分配即將不足時,0代內存分配滿了,或其他情況,微軟沒有公開該部分算法。程序員可以手動調用GC.Collect(),但是會有警告,微軟并不建議這么做。
?
? ? ?2、垃圾確認:通過根來尋找可達的對象(以后添加),并做標記,然后回收沒有標記的對象。
?
? ? ?3、垃圾回收:內存回收,對于實現了Finalize方法的對象請參考最上面1的介紹。
?
? ? ?4、內存轉移,合并。垃圾回收后使得內存不連續,零碎,.Net會將利用的內存合并為連續的塊,然后更新對象的指針。
5
?注意的地方
?
? ? ?1、值類型(包括引用和對象實例)和引用類型的引用其實是不需要什么"垃圾回收器"來釋放內存的,因為當它們出了作用域后會自動釋放所占內存(因為它們都保存在"堆棧"中,學過數據結構可知這是一種先進后出的結構);
? ? ?2、只有引用類型的引用所指向的對象實例才保存在"堆"中,而堆因為是一個自由存儲空間,所以它并沒有像"堆棧"那樣有生存期("堆棧"的元素彈出后就代 表生存期結束,也就代表釋放了內存),并且非常要注意的是,"垃圾回收器"只對這塊區域起作用;?
? ? ?3、"垃圾回收器"也許并不像許多人想象的一樣會立即執行(當堆中的資源需要釋放時),而是在引用類型的引用被刪除和它在"堆"中的對象實例被刪除中間有 個間隔,為什么呢? 因為"垃圾回收器"的調用是比較消耗系統資源的,因此不可能經常被調用!(當然,用戶代碼


可以用方法System.GC.Collect()來強制執行"垃圾回收器")
? ? 4、有析構函數的對象需要垃圾收集器兩次處理才能刪除:第一次調用析構函數時,沒有刪除對象,第二次調用才真正刪除對象。
? ? 5、由于垃圾收集器的工作方式,無法確定C#對象的析構函數何時執行。
? ? 6、可實現IDisposable接口的Dispose()來顯示釋放由對象使用的所有未托管資源。
? ? 7、垃圾收集器在釋放了它能釋放的所有對象后,就會壓縮其他對象,把他們都移動回heap的端部,再次形成一個連續的塊。
========

總結

以上是生活随笔為你收集整理的C#垃圾回收学习总结的全部內容,希望文章能夠幫你解決所遇到的問題。

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

黑森林福利视频导航 | 久久综合给久久狠狠97色 | 一个人看的www免费视频在线观看 | 久久精品人人做人人综合 | 无码中文字幕色专区 | 色综合久久久久综合一本到桃花网 | 玩弄人妻少妇500系列视频 | 亚洲精品无码人妻无码 | 国产精品无码一区二区桃花视频 | 亚洲欧美日韩综合久久久 | 特大黑人娇小亚洲女 | 成人无码视频在线观看网站 | 国产精品久久国产三级国 | 成人av无码一区二区三区 | 无码中文字幕色专区 | 天天摸天天透天天添 | 色噜噜亚洲男人的天堂 | www国产亚洲精品久久网站 | 亚洲成a人一区二区三区 | 极品嫩模高潮叫床 | 国产乱人无码伦av在线a | 国产国产精品人在线视 | 玩弄中年熟妇正在播放 | 丰满人妻翻云覆雨呻吟视频 | 国产精品高潮呻吟av久久4虎 | 又大又紧又粉嫩18p少妇 | 18无码粉嫩小泬无套在线观看 | 国产国产精品人在线视 | 欧美第一黄网免费网站 | 最新版天堂资源中文官网 | 夜夜夜高潮夜夜爽夜夜爰爰 | 国产明星裸体无码xxxx视频 | 亚洲精品www久久久 | 乌克兰少妇xxxx做受 | 红桃av一区二区三区在线无码av | 国产精品久久久久久亚洲毛片 | 欧美色就是色 | 特大黑人娇小亚洲女 | 日本精品少妇一区二区三区 | 国产乱子伦视频在线播放 | 国产综合久久久久鬼色 | 美女极度色诱视频国产 | 精品无码一区二区三区的天堂 | 亚洲色大成网站www国产 | 一个人看的视频www在线 | 欧美喷潮久久久xxxxx | 精品欧美一区二区三区久久久 | 兔费看少妇性l交大片免费 | 97久久精品无码一区二区 | 欧美老熟妇乱xxxxx | 色婷婷av一区二区三区之红樱桃 | ass日本丰满熟妇pics | 婷婷色婷婷开心五月四房播播 | 国产精品亚洲五月天高清 | 狂野欧美性猛交免费视频 | 学生妹亚洲一区二区 | 99精品无人区乱码1区2区3区 | 亚洲熟熟妇xxxx | 性生交大片免费看女人按摩摩 | 久久国产精品偷任你爽任你 | 成人免费视频视频在线观看 免费 | 久久婷婷五月综合色国产香蕉 | 亚洲码国产精品高潮在线 | 骚片av蜜桃精品一区 | 图片小说视频一区二区 | 人妻少妇被猛烈进入中文字幕 | 国产片av国语在线观看 | 欧美老人巨大xxxx做受 | 欧美阿v高清资源不卡在线播放 | 久久综合久久自在自线精品自 | 蜜桃av蜜臀av色欲av麻 999久久久国产精品消防器材 | 国产精品18久久久久久麻辣 | 夫妻免费无码v看片 | 性生交大片免费看女人按摩摩 | 黑人巨大精品欧美黑寡妇 | 精品偷拍一区二区三区在线看 | 精品亚洲韩国一区二区三区 | av无码不卡在线观看免费 | 丁香花在线影院观看在线播放 | 最新国产麻豆aⅴ精品无码 | 青青青手机频在线观看 | 亚洲精品一区二区三区在线 | 无码精品人妻一区二区三区av | 最近的中文字幕在线看视频 | 人人澡人人妻人人爽人人蜜桃 | 欧美乱妇无乱码大黄a片 | 久久99精品国产麻豆蜜芽 | 性做久久久久久久久 | 免费男性肉肉影院 | 国产人妻精品一区二区三区 | 欧美野外疯狂做受xxxx高潮 | 久久99久久99精品中文字幕 | 内射欧美老妇wbb | 国产超碰人人爽人人做人人添 | 蜜臀aⅴ国产精品久久久国产老师 | 国产97人人超碰caoprom | 久久精品国产99久久6动漫 | 国产情侣作爱视频免费观看 | 对白脏话肉麻粗话av | 日日碰狠狠丁香久燥 | 久久久国产精品无码免费专区 | 国产精品.xx视频.xxtv | 精品国产国产综合精品 | 亚洲一区二区三区四区 | 免费国产黄网站在线观看 | av无码电影一区二区三区 | 麻豆果冻传媒2021精品传媒一区下载 | 国产艳妇av在线观看果冻传媒 | 夜夜躁日日躁狠狠久久av | 蜜桃av蜜臀av色欲av麻 999久久久国产精品消防器材 | 国产亚洲精品精品国产亚洲综合 | 无码人妻精品一区二区三区不卡 | 久久久久亚洲精品中文字幕 | 人妻人人添人妻人人爱 | 久久 国产 尿 小便 嘘嘘 | 午夜福利电影 | 成人毛片一区二区 | 国产超级va在线观看视频 | www国产亚洲精品久久网站 | 国产suv精品一区二区五 | 国产成人无码av片在线观看不卡 | 亚洲综合无码久久精品综合 | 国产成人精品无码播放 | 少妇无码吹潮 | 国产一区二区不卡老阿姨 | 国产精品国产自线拍免费软件 | 免费人成在线观看网站 | 国产在线一区二区三区四区五区 | 免费视频欧美无人区码 | 漂亮人妻洗澡被公强 日日躁 | 久久精品国产日本波多野结衣 | 国产成人精品视频ⅴa片软件竹菊 | 高潮毛片无遮挡高清免费视频 | 亚洲春色在线视频 | 国产精品第一国产精品 | 国产精品美女久久久久av爽李琼 | 久久99精品国产麻豆蜜芽 | а√资源新版在线天堂 | av人摸人人人澡人人超碰下载 | 麻豆蜜桃av蜜臀av色欲av | 性啪啪chinese东北女人 | 精品乱码久久久久久久 | 麻豆精品国产精华精华液好用吗 | 亚洲成av人片天堂网无码】 | 特黄特色大片免费播放器图片 | 四虎4hu永久免费 | 性啪啪chinese东北女人 | 7777奇米四色成人眼影 | 人妻互换免费中文字幕 | 日韩av无码一区二区三区不卡 | 夜夜高潮次次欢爽av女 | 久久精品视频在线看15 | 久久久久久九九精品久 | 中文字幕亚洲情99在线 | 亚洲欧美国产精品专区久久 | av在线亚洲欧洲日产一区二区 | 九九热爱视频精品 | 亚洲一区二区三区香蕉 | 国产精品久久久久久久影院 | 性做久久久久久久久 | 国产成人无码一二三区视频 | 呦交小u女精品视频 | 少妇性荡欲午夜性开放视频剧场 | 国产片av国语在线观看 | 欧美三级不卡在线观看 | 日本一本二本三区免费 | 久久亚洲日韩精品一区二区三区 | 免费观看激色视频网站 | 婷婷丁香六月激情综合啪 | 无码精品人妻一区二区三区av | 国产成人综合在线女婷五月99播放 | 亚洲va欧美va天堂v国产综合 | 欧美放荡的少妇 | 成人三级无码视频在线观看 | 六月丁香婷婷色狠狠久久 | 国产三级久久久精品麻豆三级 | 强伦人妻一区二区三区视频18 | 少妇性荡欲午夜性开放视频剧场 | 日产国产精品亚洲系列 | 十八禁真人啪啪免费网站 | 国产卡一卡二卡三 | 精品无码成人片一区二区98 | 99久久精品日本一区二区免费 | 中文字幕人成乱码熟女app | 国产香蕉尹人视频在线 | 国产区女主播在线观看 | 伊人色综合久久天天小片 | 图片小说视频一区二区 | 在线天堂新版最新版在线8 | 人人爽人人澡人人高潮 | 超碰97人人做人人爱少妇 | 亚洲爆乳精品无码一区二区三区 | 国语精品一区二区三区 | 国产精品久久久久久亚洲影视内衣 | 无码人妻精品一区二区三区不卡 | 激情亚洲一区国产精品 | 欧美高清在线精品一区 | 双乳奶水饱满少妇呻吟 | 欧美老妇与禽交 | аⅴ资源天堂资源库在线 | 亚洲精品欧美二区三区中文字幕 | 国产乱人伦app精品久久 国产在线无码精品电影网 国产国产精品人在线视 | 四虎国产精品免费久久 | 中国女人内谢69xxxxxa片 | 国产电影无码午夜在线播放 | 亚洲国产精品美女久久久久 | 思思久久99热只有频精品66 | 日本又色又爽又黄的a片18禁 | 亚洲中文字幕在线无码一区二区 | 在线精品亚洲一区二区 | 国产精品久久久久久久9999 | 中文字幕av伊人av无码av | 欧美xxxx黑人又粗又长 | 日本肉体xxxx裸交 | 国产精品办公室沙发 | 98国产精品综合一区二区三区 | 欧美丰满熟妇xxxx性ppx人交 | 亚洲精品国产精品乱码视色 | 少妇高潮喷潮久久久影院 | 日韩精品a片一区二区三区妖精 | 欧美精品在线观看 | 骚片av蜜桃精品一区 | 色 综合 欧美 亚洲 国产 | 国产精品久久久久9999小说 | 夜先锋av资源网站 | 成年女人永久免费看片 | 国产成人人人97超碰超爽8 | 免费网站看v片在线18禁无码 | √8天堂资源地址中文在线 | 99久久精品国产一区二区蜜芽 | 少妇无码一区二区二三区 | 红桃av一区二区三区在线无码av | 国产手机在线αⅴ片无码观看 | 亚洲小说春色综合另类 | 一本大道伊人av久久综合 | 成人三级无码视频在线观看 | 综合激情五月综合激情五月激情1 | 色偷偷人人澡人人爽人人模 | 人妻aⅴ无码一区二区三区 | 久久zyz资源站无码中文动漫 | 性欧美牲交在线视频 | 中文字幕乱妇无码av在线 | 国产亚洲精品久久久久久大师 | 久激情内射婷内射蜜桃人妖 | 亚洲а∨天堂久久精品2021 | 午夜无码人妻av大片色欲 | 午夜性刺激在线视频免费 | 久久精品丝袜高跟鞋 | 曰韩无码二三区中文字幕 | 午夜福利试看120秒体验区 | 亚洲精品中文字幕久久久久 | 无码人妻丰满熟妇区毛片18 | 亚洲欧洲日本综合aⅴ在线 | 国产人妻人伦精品 | 国产精品内射视频免费 | 精品久久久久香蕉网 | 人妻与老人中文字幕 | 国产凸凹视频一区二区 | 青青青爽视频在线观看 | 亚洲成av人在线观看网址 | 日韩人妻少妇一区二区三区 | 黄网在线观看免费网站 | 亚洲精品一区二区三区在线观看 | 午夜精品久久久内射近拍高清 | √8天堂资源地址中文在线 | 亚洲国产一区二区三区在线观看 | 国产精品人人爽人人做我的可爱 | 国产尤物精品视频 | 国产免费观看黄av片 | 少妇性俱乐部纵欲狂欢电影 | 99视频精品全部免费免费观看 | 夜夜高潮次次欢爽av女 | 欧美性猛交xxxx富婆 | 国产无av码在线观看 | 日韩av无码中文无码电影 | 无遮挡国产高潮视频免费观看 | 美女毛片一区二区三区四区 | 国内少妇偷人精品视频免费 | 亚洲の无码国产の无码影院 | 欧美阿v高清资源不卡在线播放 | 乱人伦人妻中文字幕无码久久网 | 性欧美videos高清精品 | 好屌草这里只有精品 | 少妇被黑人到高潮喷出白浆 | 初尝人妻少妇中文字幕 | 欧美丰满少妇xxxx性 | 一本加勒比波多野结衣 | 精品少妇爆乳无码av无码专区 | 色综合视频一区二区三区 | 亚拍精品一区二区三区探花 | 国产人妖乱国产精品人妖 | 在线亚洲高清揄拍自拍一品区 | 天干天干啦夜天干天2017 | 色综合天天综合狠狠爱 | 久久久久成人片免费观看蜜芽 | 久久精品中文字幕一区 | 亚洲 另类 在线 欧美 制服 | 正在播放老肥熟妇露脸 | 日韩av无码一区二区三区不卡 | 奇米综合四色77777久久 东京无码熟妇人妻av在线网址 | 国产亚洲欧美日韩亚洲中文色 | 亚洲热妇无码av在线播放 | 欧美亚洲日韩国产人成在线播放 | 婷婷五月综合缴情在线视频 | 无码午夜成人1000部免费视频 | 久久99精品久久久久婷婷 | 久久精品国产一区二区三区肥胖 | 国产明星裸体无码xxxx视频 | 亚洲人成无码网www | 久久国产精品二国产精品 | 特级做a爰片毛片免费69 | 国产国语老龄妇女a片 | 丰满少妇女裸体bbw | 欧美激情综合亚洲一二区 | 久久视频在线观看精品 | 国产特级毛片aaaaaa高潮流水 | 无码国模国产在线观看 | 欧美兽交xxxx×视频 | 蜜桃视频韩日免费播放 | 亚洲精品一区三区三区在线观看 | 少女韩国电视剧在线观看完整 | 亚洲精品一区三区三区在线观看 | 久久久成人毛片无码 | 国产成人精品无码播放 | 无码国模国产在线观看 | 澳门永久av免费网站 | 对白脏话肉麻粗话av | 中文字幕人妻无码一区二区三区 | 国产人妻精品一区二区三区不卡 | 激情人妻另类人妻伦 | av香港经典三级级 在线 | 高潮喷水的毛片 | 日韩在线不卡免费视频一区 | 国产在线精品一区二区高清不卡 | 久久久久亚洲精品中文字幕 | а√天堂www在线天堂小说 | 亚洲乱亚洲乱妇50p | 天天摸天天碰天天添 | 亚洲の无码国产の无码影院 | 在线观看免费人成视频 | 欧美日韩视频无码一区二区三 | 娇妻被黑人粗大高潮白浆 | 久久99久久99精品中文字幕 | 2020最新国产自产精品 | 精品亚洲韩国一区二区三区 | 女人和拘做爰正片视频 | 亚洲中文字幕无码中字 | 在线看片无码永久免费视频 | 国内精品人妻无码久久久影院蜜桃 | 国产精品-区区久久久狼 | 夜精品a片一区二区三区无码白浆 | 久久精品成人欧美大片 | 久激情内射婷内射蜜桃人妖 | 色婷婷香蕉在线一区二区 | 高潮喷水的毛片 | 亚洲欧美日韩成人高清在线一区 | 日本欧美一区二区三区乱码 | 亚洲综合精品香蕉久久网 | 欧美老妇与禽交 | 精品欧美一区二区三区久久久 | 亚洲 另类 在线 欧美 制服 | 国产精品-区区久久久狼 | 久久久久免费看成人影片 | 97se亚洲精品一区 | 国产精品第一国产精品 | 鲁大师影院在线观看 | 成在人线av无码免观看麻豆 | 亚洲性无码av中文字幕 | 亚洲精品一区二区三区在线 | 久久视频在线观看精品 | 久久久久久av无码免费看大片 | 国产精品亚洲一区二区三区喷水 | 国产精品无码永久免费888 | 精品日本一区二区三区在线观看 | 欧美日韩人成综合在线播放 | 国产精品久久福利网站 | 国产无套粉嫩白浆在线 | 午夜福利试看120秒体验区 | av无码电影一区二区三区 | 3d动漫精品啪啪一区二区中 | 丝袜 中出 制服 人妻 美腿 | 东京热男人av天堂 | 亚洲国产精品无码一区二区三区 | 黑人巨大精品欧美一区二区 | √8天堂资源地址中文在线 | 无码av最新清无码专区吞精 | 精品一区二区三区波多野结衣 | 欧美性色19p | 国内精品九九久久久精品 | 亚洲综合另类小说色区 | 国产熟妇另类久久久久 | 欧美性猛交内射兽交老熟妇 | 国産精品久久久久久久 | 国产乱人无码伦av在线a | 夜夜高潮次次欢爽av女 | 7777奇米四色成人眼影 | 国产精品无码一区二区三区不卡 | 99精品无人区乱码1区2区3区 | 国产农村乱对白刺激视频 | 午夜不卡av免费 一本久久a久久精品vr综合 | 伊在人天堂亚洲香蕉精品区 | 双乳奶水饱满少妇呻吟 | 麻豆精品国产精华精华液好用吗 | 成人片黄网站色大片免费观看 | 日韩精品无码一本二本三本色 | 中文字幕中文有码在线 | 成人免费视频视频在线观看 免费 | 亚洲呦女专区 | 国产av一区二区三区最新精品 | 精品人人妻人人澡人人爽人人 | 久久久中文久久久无码 | 久久精品中文字幕一区 | 九月婷婷人人澡人人添人人爽 | 国产亚av手机在线观看 | 国产成人无码av片在线观看不卡 | 欧美变态另类xxxx | 久久久久av无码免费网 | 无码人妻丰满熟妇区五十路百度 | 婷婷色婷婷开心五月四房播播 | 狠狠噜狠狠狠狠丁香五月 | 日韩精品成人一区二区三区 | 精品无人区无码乱码毛片国产 | 中文字幕久久久久人妻 | 欧美精品国产综合久久 | 性色欲情网站iwww九文堂 | 亲嘴扒胸摸屁股激烈网站 | 成人精品一区二区三区中文字幕 | 露脸叫床粗话东北少妇 | 图片区 小说区 区 亚洲五月 | 国产精品怡红院永久免费 | 国产成人亚洲综合无码 | 亚洲国产精华液网站w | 欧美国产日韩亚洲中文 | 亚洲人亚洲人成电影网站色 | 亚洲中文字幕成人无码 | 97精品国产97久久久久久免费 | 国内精品久久久久久中文字幕 | 国产另类ts人妖一区二区 | 高清不卡一区二区三区 | 特大黑人娇小亚洲女 | 麻豆国产97在线 | 欧洲 | 午夜免费福利小电影 | 亚洲成av人片在线观看无码不卡 | 无套内谢的新婚少妇国语播放 | 亚洲一区av无码专区在线观看 | 国产精品久久精品三级 | 中文字幕乱码中文乱码51精品 | 国产av剧情md精品麻豆 | 清纯唯美经典一区二区 | 国产亚洲视频中文字幕97精品 | 麻豆人妻少妇精品无码专区 | 婷婷五月综合激情中文字幕 | 国产精品高潮呻吟av久久4虎 | 妺妺窝人体色www婷婷 | 国产三级久久久精品麻豆三级 | 国产真实夫妇视频 | 欧美人与禽猛交狂配 | 无码一区二区三区在线 | 成人精品天堂一区二区三区 | 国产suv精品一区二区五 | 亚洲gv猛男gv无码男同 | 丝袜足控一区二区三区 | 亚洲自偷自偷在线制服 | 国产综合久久久久鬼色 | 久久午夜无码鲁丝片秋霞 | 一个人看的视频www在线 | 乱码午夜-极国产极内射 | v一区无码内射国产 | 99国产精品白浆在线观看免费 | 国产精品福利视频导航 | 一个人看的www免费视频在线观看 | 欧美 亚洲 国产 另类 | 99国产欧美久久久精品 | √天堂中文官网8在线 | 国产莉萝无码av在线播放 | 欧美 亚洲 国产 另类 | 亚洲色www成人永久网址 | 国产av剧情md精品麻豆 | аⅴ资源天堂资源库在线 | 亚洲精品欧美二区三区中文字幕 | 白嫩日本少妇做爰 | 日韩人妻无码一区二区三区久久99 | 亚洲欧美国产精品久久 | 亚洲精品中文字幕久久久久 | 日本一卡2卡3卡4卡无卡免费网站 国产一区二区三区影院 | 国产在线aaa片一区二区99 | 人妻天天爽夜夜爽一区二区 | 蜜桃臀无码内射一区二区三区 | 亚洲日韩乱码中文无码蜜桃臀网站 | 国产肉丝袜在线观看 | 奇米影视888欧美在线观看 | 思思久久99热只有频精品66 | 天天摸天天透天天添 | 天天爽夜夜爽夜夜爽 | 全黄性性激高免费视频 | 久久久久久亚洲精品a片成人 | 久久国产精品_国产精品 | 无码国产激情在线观看 | 真人与拘做受免费视频 | 日韩精品无码一区二区中文字幕 | 国产人妻精品一区二区三区 | 国产又粗又硬又大爽黄老大爷视 | 福利一区二区三区视频在线观看 | 99视频精品全部免费免费观看 | 亚洲国产精华液网站w | 日产国产精品亚洲系列 | 爽爽影院免费观看 | 青青草原综合久久大伊人精品 | 国产精品久久久久久久9999 | 国产精品办公室沙发 | 美女黄网站人色视频免费国产 | 中文久久乱码一区二区 | 亚洲自偷自偷在线制服 | 亚洲爆乳大丰满无码专区 | 2020最新国产自产精品 | 国产97在线 | 亚洲 | 伊人久久大香线焦av综合影院 | 成人无码精品一区二区三区 | 日本免费一区二区三区最新 | 性啪啪chinese东北女人 | 色欲人妻aaaaaaa无码 | 日本一卡二卡不卡视频查询 | 爱做久久久久久 | 黑人大群体交免费视频 | 精品 日韩 国产 欧美 视频 | 精品 日韩 国产 欧美 视频 | 中文字幕av日韩精品一区二区 | www国产亚洲精品久久久日本 | 麻豆国产97在线 | 欧洲 | 国内精品人妻无码久久久影院 | 亚洲精品欧美二区三区中文字幕 | 色综合久久久久综合一本到桃花网 | 大屁股大乳丰满人妻 | 无码成人精品区在线观看 | 久久久精品人妻久久影视 | 妺妺窝人体色www在线小说 | 中文字幕久久久久人妻 | 国产无套粉嫩白浆在线 | 亚洲精品一区二区三区在线 | 人妻互换免费中文字幕 | 成 人 免费观看网站 | 国产网红无码精品视频 | 国产亚洲欧美日韩亚洲中文色 | 国产综合在线观看 | 色婷婷香蕉在线一区二区 | 99久久久国产精品无码免费 | 国产猛烈高潮尖叫视频免费 | 老子影院午夜伦不卡 | 天天拍夜夜添久久精品 | 红桃av一区二区三区在线无码av | 高中生自慰www网站 | 国产亚洲精品久久久ai换 | 欧美精品国产综合久久 | 少妇被粗大的猛进出69影院 | 天天躁夜夜躁狠狠是什么心态 | 激情内射日本一区二区三区 | 精品成在人线av无码免费看 | 欧美精品免费观看二区 | 女人被男人爽到呻吟的视频 | 久久精品人人做人人综合试看 | 四虎影视成人永久免费观看视频 | 撕开奶罩揉吮奶头视频 | 天天爽夜夜爽夜夜爽 | а√天堂www在线天堂小说 | 国产人妻精品一区二区三区不卡 | 麻豆国产人妻欲求不满 | 国产午夜亚洲精品不卡下载 | 思思久久99热只有频精品66 | 国产成人av免费观看 | 在线观看欧美一区二区三区 | 久久亚洲中文字幕精品一区 | 亚洲乱亚洲乱妇50p | 丰满人妻一区二区三区免费视频 | 99麻豆久久久国产精品免费 | 亚洲中文字幕在线无码一区二区 | 伊人久久大香线蕉午夜 | 99久久久无码国产aaa精品 | 俺去俺来也www色官网 | 国产精品久久久午夜夜伦鲁鲁 | 给我免费的视频在线观看 | 国产真实夫妇视频 | 精品国产av色一区二区深夜久久 | 2020久久香蕉国产线看观看 | 熟妇女人妻丰满少妇中文字幕 | 精品无码国产自产拍在线观看蜜 | 国产精品欧美成人 | 国产精品亚洲五月天高清 | 日本一区二区三区免费高清 | 熟女体下毛毛黑森林 | 国产热a欧美热a在线视频 | 午夜成人1000部免费视频 | 国产免费无码一区二区视频 | 久久无码中文字幕免费影院蜜桃 | 久久综合香蕉国产蜜臀av | 日日碰狠狠丁香久燥 | 成人欧美一区二区三区黑人免费 | 亚洲精品国偷拍自产在线麻豆 | 国产精品久久久久9999小说 | 老子影院午夜精品无码 | 欧美黑人性暴力猛交喷水 | 国产亚洲精品久久久ai换 | 一本无码人妻在中文字幕免费 | 无码国产乱人伦偷精品视频 | 国产人妻精品一区二区三区 | 国产人妻人伦精品1国产丝袜 | 久久99精品久久久久久动态图 | 色婷婷综合中文久久一本 | 伊人久久婷婷五月综合97色 | 成人一区二区免费视频 | 波多野结衣高清一区二区三区 | 国产成人人人97超碰超爽8 | 扒开双腿疯狂进出爽爽爽视频 | 欧美黑人巨大xxxxx | 日韩亚洲欧美中文高清在线 | 性欧美大战久久久久久久 | 亚洲a无码综合a国产av中文 | 亚洲精品国产a久久久久久 | 亚洲va欧美va天堂v国产综合 | 伊在人天堂亚洲香蕉精品区 | 成人免费视频视频在线观看 免费 | 亚洲欧美日韩成人高清在线一区 | 亚洲精品综合一区二区三区在线 | 久久综合九色综合欧美狠狠 | 久久天天躁狠狠躁夜夜免费观看 | 国产女主播喷水视频在线观看 | 俄罗斯老熟妇色xxxx | 秋霞成人午夜鲁丝一区二区三区 | 成年美女黄网站色大免费视频 | 婷婷五月综合缴情在线视频 | 夜夜高潮次次欢爽av女 | 国产在线精品一区二区三区直播 | 蜜桃av蜜臀av色欲av麻 999久久久国产精品消防器材 | 性啪啪chinese东北女人 | 欧美成人午夜精品久久久 | 久久精品无码一区二区三区 | 成人aaa片一区国产精品 | 色噜噜亚洲男人的天堂 | 九月婷婷人人澡人人添人人爽 | 熟妇女人妻丰满少妇中文字幕 | 亚洲无人区一区二区三区 | 国产一精品一av一免费 | 在线亚洲高清揄拍自拍一品区 | 亚洲aⅴ无码成人网站国产app | 色综合久久网 | 久久99精品国产麻豆蜜芽 | 成人无码影片精品久久久 | 欧美激情一区二区三区成人 | 欧美国产亚洲日韩在线二区 | 伊人久久大香线蕉av一区二区 | 欧美刺激性大交 | 亚洲精品一区二区三区大桥未久 | 欧美性猛交xxxx富婆 | 色综合久久久无码中文字幕 | 欧美熟妇另类久久久久久不卡 | 天海翼激烈高潮到腰振不止 | аⅴ资源天堂资源库在线 | 久久婷婷五月综合色国产香蕉 | 国产麻豆精品精东影业av网站 | 久久久精品国产sm最大网站 | a片免费视频在线观看 | 久久亚洲国产成人精品性色 | 99久久久无码国产aaa精品 | 国产一区二区不卡老阿姨 | 亚洲人成影院在线观看 | 色爱情人网站 | 久久人妻内射无码一区三区 | 亚洲熟妇色xxxxx亚洲 | 国产特级毛片aaaaaa高潮流水 | 香港三级日本三级妇三级 | 国产成人午夜福利在线播放 | 永久免费观看美女裸体的网站 | 色婷婷综合激情综在线播放 | 日本一卡2卡3卡4卡无卡免费网站 国产一区二区三区影院 | 2020久久香蕉国产线看观看 | 久激情内射婷内射蜜桃人妖 | 国产色精品久久人妻 | 亚洲日韩中文字幕在线播放 | 国产黄在线观看免费观看不卡 | 西西人体www44rt大胆高清 | 成人欧美一区二区三区 | 大乳丰满人妻中文字幕日本 | 特大黑人娇小亚洲女 | 又紧又大又爽精品一区二区 | 国产精品第一国产精品 | 久久久久se色偷偷亚洲精品av | 少妇性荡欲午夜性开放视频剧场 | 日本一卡2卡3卡四卡精品网站 | 亚洲中文字幕无码中文字在线 | 国产麻豆精品一区二区三区v视界 | 领导边摸边吃奶边做爽在线观看 | 亚洲精品久久久久中文第一幕 | 亚洲人成网站免费播放 | 牲欲强的熟妇农村老妇女视频 | 97se亚洲精品一区 | 少妇太爽了在线观看 | 亚洲精品综合一区二区三区在线 | 色综合久久久久综合一本到桃花网 | 激情综合激情五月俺也去 | 激情国产av做激情国产爱 | 国产亚洲精品精品国产亚洲综合 | 亚洲码国产精品高潮在线 | 国产va免费精品观看 | 欧美人与物videos另类 | 377p欧洲日本亚洲大胆 | 四十如虎的丰满熟妇啪啪 | 亚洲精品中文字幕乱码 | 黑人玩弄人妻中文在线 | 精品无码国产自产拍在线观看蜜 | 欧美日韩久久久精品a片 | 国产精品久久久一区二区三区 | 午夜精品久久久内射近拍高清 | 久久久成人毛片无码 | 日本一卡2卡3卡四卡精品网站 | 欧美变态另类xxxx | 熟妇人妻无乱码中文字幕 | 国产精品久久久久久久影院 | 亚洲人成无码网www | 免费网站看v片在线18禁无码 | 精品国产乱码久久久久乱码 | 18精品久久久无码午夜福利 | 久久久久国色av免费观看性色 | 在线视频网站www色 | 国产精品爱久久久久久久 | 国产一精品一av一免费 | 乌克兰少妇xxxx做受 | 久久精品女人天堂av免费观看 | 国产明星裸体无码xxxx视频 | 亚洲精品国偷拍自产在线麻豆 | 久久人妻内射无码一区三区 | 久久久无码中文字幕久... | 国产人妻久久精品二区三区老狼 | 精品久久综合1区2区3区激情 | 精品亚洲韩国一区二区三区 | 亚洲欧美国产精品专区久久 | 午夜时刻免费入口 | 思思久久99热只有频精品66 | 亚洲一区二区三区国产精华液 | 超碰97人人做人人爱少妇 | 强辱丰满人妻hd中文字幕 | 国产av剧情md精品麻豆 | 婷婷综合久久中文字幕蜜桃三电影 | 清纯唯美经典一区二区 | 成年美女黄网站色大免费视频 | 国产一精品一av一免费 | 捆绑白丝粉色jk震动捧喷白浆 | 日日天日日夜日日摸 | 国产无套粉嫩白浆在线 | 激情爆乳一区二区三区 | 亚洲成a人片在线观看无码 | 风流少妇按摩来高潮 | 午夜时刻免费入口 | 成人欧美一区二区三区 | 秋霞特色aa大片 | 少妇无套内谢久久久久 | 国产精品国产三级国产专播 | 亚洲国产精品毛片av不卡在线 | 99久久久无码国产aaa精品 | 性欧美大战久久久久久久 | 免费无码av一区二区 | 日韩精品成人一区二区三区 | 精品无人区无码乱码毛片国产 | 国产疯狂伦交大片 | 无码国产激情在线观看 | 国产精品香蕉在线观看 | 日本免费一区二区三区最新 | 久久久久人妻一区精品色欧美 | 又湿又紧又大又爽a视频国产 | 欧美性猛交xxxx富婆 | 亚洲呦女专区 | 性生交大片免费看l | 欧美精品无码一区二区三区 | 亚洲娇小与黑人巨大交 | 亚洲精品国产精品乱码视色 | 无套内射视频囯产 | 亚洲色大成网站www | 国产两女互慰高潮视频在线观看 | 久久这里只有精品视频9 | 色五月五月丁香亚洲综合网 | 久久99精品久久久久久 | 日本va欧美va欧美va精品 | 牲欲强的熟妇农村老妇女 | 国产精品美女久久久 | 国产免费无码一区二区视频 | 国产成人无码av片在线观看不卡 | 欧美性猛交内射兽交老熟妇 | 久久无码中文字幕免费影院蜜桃 | 日本熟妇浓毛 | 香蕉久久久久久av成人 | 日本www一道久久久免费榴莲 | 久久综合色之久久综合 | 鲁鲁鲁爽爽爽在线视频观看 | 99久久精品日本一区二区免费 | 极品嫩模高潮叫床 | 无码纯肉视频在线观看 | 国产99久久精品一区二区 | 成人精品天堂一区二区三区 | 久久综合九色综合欧美狠狠 | 色 综合 欧美 亚洲 国产 | 无套内谢的新婚少妇国语播放 | 99国产欧美久久久精品 | 婷婷色婷婷开心五月四房播播 | 精品无码一区二区三区的天堂 | 久久精品国产一区二区三区肥胖 | 好男人www社区 | 久久午夜无码鲁丝片 | 丰满少妇人妻久久久久久 | 国产真实夫妇视频 | 天天摸天天碰天天添 | 午夜性刺激在线视频免费 | 欧美老妇与禽交 | 天天燥日日燥 | 国产成人亚洲综合无码 | 精品人妻人人做人人爽 | 少妇一晚三次一区二区三区 | 在线欧美精品一区二区三区 | 国产一区二区三区日韩精品 | 麻豆果冻传媒2021精品传媒一区下载 | 欧美一区二区三区 | 人人爽人人澡人人高潮 | 天堂亚洲免费视频 | 蜜臀aⅴ国产精品久久久国产老师 | 女人和拘做爰正片视频 | 强伦人妻一区二区三区视频18 | 亚洲の无码国产の无码影院 | 国产成人精品无码播放 | 性色欲网站人妻丰满中文久久不卡 | 日韩在线不卡免费视频一区 | 国产va免费精品观看 | 成人性做爰aaa片免费看不忠 | 亚洲狠狠婷婷综合久久 | 国产香蕉尹人视频在线 | 国产热a欧美热a在线视频 | 在线a亚洲视频播放在线观看 | 国产综合在线观看 | 日韩精品无码一区二区中文字幕 | 色婷婷欧美在线播放内射 | 成年美女黄网站色大免费全看 | 国产亲子乱弄免费视频 | 蜜桃无码一区二区三区 | 人妻无码αv中文字幕久久琪琪布 | 丰满人妻一区二区三区免费视频 | 国产成人一区二区三区在线观看 | 综合人妻久久一区二区精品 | 亚洲第一无码av无码专区 | 在线天堂新版最新版在线8 | 娇妻被黑人粗大高潮白浆 | 国产区女主播在线观看 | 无码国模国产在线观看 | a片在线免费观看 | 18禁止看的免费污网站 | 精品日本一区二区三区在线观看 | 99国产精品白浆在线观看免费 | 国产免费无码一区二区视频 | 性生交片免费无码看人 | 日本熟妇浓毛 | 熟妇人妻激情偷爽文 | 国产亚洲精品久久久久久大师 | 国产麻豆精品精东影业av网站 | 成人性做爰aaa片免费看 | 青草青草久热国产精品 | 国产绳艺sm调教室论坛 | 国产麻豆精品一区二区三区v视界 | 色噜噜亚洲男人的天堂 | 亚洲小说春色综合另类 | 高清不卡一区二区三区 | 国产精品美女久久久久av爽李琼 | 午夜理论片yy44880影院 | 亚洲成a人片在线观看无码 | 免费无码午夜福利片69 | 亚洲中文字幕无码一久久区 | 麻豆精品国产精华精华液好用吗 | 久久久久久av无码免费看大片 | 国内丰满熟女出轨videos | 暴力强奷在线播放无码 | 无码人妻精品一区二区三区不卡 | а天堂中文在线官网 | 久久综合网欧美色妞网 | 国产成人无码午夜视频在线观看 | 国产高清av在线播放 | 荫蒂添的好舒服视频囗交 | 少妇一晚三次一区二区三区 | 亚洲国产av精品一区二区蜜芽 | 国产区女主播在线观看 | 精品人人妻人人澡人人爽人人 | 国产成人无码av片在线观看不卡 | 午夜成人1000部免费视频 | 少妇愉情理伦片bd | 亚洲无人区一区二区三区 | 亚洲国产欧美日韩精品一区二区三区 | 国产精品人人爽人人做我的可爱 | 欧美日本日韩 | 中文亚洲成a人片在线观看 | 久久精品99久久香蕉国产色戒 | 亚洲另类伦春色综合小说 | 人妻与老人中文字幕 | 国产乱人伦av在线无码 | 亚洲欧美国产精品久久 | 久热国产vs视频在线观看 | 午夜性刺激在线视频免费 | 丁香啪啪综合成人亚洲 | 中文无码成人免费视频在线观看 | 欧美丰满少妇xxxx性 | 亚洲综合另类小说色区 | 国产精品高潮呻吟av久久 | 九月婷婷人人澡人人添人人爽 | 欧美日韩亚洲国产精品 | 日本爽爽爽爽爽爽在线观看免 | 亚洲色欲色欲天天天www | 国产情侣作爱视频免费观看 | 国产肉丝袜在线观看 | 国产精品毛多多水多 | 国产精品亚洲а∨无码播放麻豆 | 国产做国产爱免费视频 | 亚洲国产精品久久人人爱 | 99久久婷婷国产综合精品青草免费 | 老司机亚洲精品影院无码 | 久久综合九色综合欧美狠狠 | 高清国产亚洲精品自在久久 | 免费无码一区二区三区蜜桃大 | 精品国产一区av天美传媒 | 亚洲成av人影院在线观看 | 久久国产精品二国产精品 | 又色又爽又黄的美女裸体网站 | 人人妻人人澡人人爽精品欧美 | 亚洲一区二区三区香蕉 | 亚洲人亚洲人成电影网站色 | 中国女人内谢69xxxx | 精品一区二区三区无码免费视频 | 久久精品中文闷骚内射 | 亚洲乱亚洲乱妇50p | 日韩无套无码精品 | 熟妇人妻激情偷爽文 | 亚洲熟妇色xxxxx欧美老妇 | 成人无码视频在线观看网站 | 亲嘴扒胸摸屁股激烈网站 | 亚洲国产av精品一区二区蜜芽 | 久久精品人妻少妇一区二区三区 | 一个人看的www免费视频在线观看 | 精品无码av一区二区三区 | 蜜臀av无码人妻精品 | 国产欧美熟妇另类久久久 | 日日摸夜夜摸狠狠摸婷婷 | 国产国产精品人在线视 | 丝袜 中出 制服 人妻 美腿 | 久久综合九色综合97网 | 老子影院午夜伦不卡 | 亚洲精品国产品国语在线观看 | 55夜色66夜色国产精品视频 | 久久这里只有精品视频9 | 国产精品美女久久久 | 亚洲日韩av一区二区三区四区 | 国产精品亚洲а∨无码播放麻豆 | 女人被男人躁得好爽免费视频 | 日本精品少妇一区二区三区 | 成人欧美一区二区三区黑人免费 | 青草视频在线播放 | 中文无码伦av中文字幕 | 国产口爆吞精在线视频 | 一个人看的www免费视频在线观看 | 国产超碰人人爽人人做人人添 | 久久综合香蕉国产蜜臀av | 久久久久亚洲精品中文字幕 | 国产偷自视频区视频 | 中国女人内谢69xxxx | 水蜜桃色314在线观看 | 波多野结衣一区二区三区av免费 | 久久亚洲日韩精品一区二区三区 | 动漫av一区二区在线观看 | 国产亚洲欧美在线专区 | 77777熟女视频在线观看 а天堂中文在线官网 | 国产农村妇女高潮大叫 | 无码午夜成人1000部免费视频 | 精品无码一区二区三区爱欲 | 欧美日韩视频无码一区二区三 | 无套内谢的新婚少妇国语播放 | 小鲜肉自慰网站xnxx | 粉嫩少妇内射浓精videos | 国产精品资源一区二区 | 日本又色又爽又黄的a片18禁 | 亚洲国产午夜精品理论片 | 亚洲国产成人av在线观看 | 国产肉丝袜在线观看 | 在线看片无码永久免费视频 | 精品一区二区三区无码免费视频 | 无码福利日韩神码福利片 | 天干天干啦夜天干天2017 | 亚洲午夜无码久久 | 曰韩少妇内射免费播放 | 国产在线精品一区二区高清不卡 | 97se亚洲精品一区 | 日本高清一区免费中文视频 | 久久综合九色综合97网 | 在线播放无码字幕亚洲 | 波多野结衣乳巨码无在线观看 | 牲欲强的熟妇农村老妇女视频 | 大地资源网第二页免费观看 | 日本精品久久久久中文字幕 | 欧美性色19p | 人妻有码中文字幕在线 | 精品国产一区二区三区四区在线看 | 国产精品久久国产精品99 | 成人aaa片一区国产精品 | 色婷婷av一区二区三区之红樱桃 | 人妻插b视频一区二区三区 | 久久99国产综合精品 | 男女超爽视频免费播放 | 日日躁夜夜躁狠狠躁 | 精品无人国产偷自产在线 | 欧美日韩人成综合在线播放 | 国产偷抇久久精品a片69 | 国产精品沙发午睡系列 | 7777奇米四色成人眼影 | 一本久道久久综合狠狠爱 | 色婷婷香蕉在线一区二区 | 欧美三级a做爰在线观看 | 久久久久人妻一区精品色欧美 | 国产精品自产拍在线观看 | 国产精品无码mv在线观看 | 久久zyz资源站无码中文动漫 | 亚洲国产av精品一区二区蜜芽 | 欧美性生交xxxxx久久久 | 免费看少妇作爱视频 | 人妻少妇精品无码专区动漫 | 99精品久久毛片a片 | 精品欧洲av无码一区二区三区 | 色婷婷综合中文久久一本 | 精品午夜福利在线观看 | 人妻插b视频一区二区三区 | 国产香蕉97碰碰久久人人 | 久久精品一区二区三区四区 | 国产人妻精品一区二区三区 | 亚洲国产欧美在线成人 | 天下第一社区视频www日本 | 国产精品丝袜黑色高跟鞋 | 国内精品一区二区三区不卡 | 精品国偷自产在线视频 | √天堂资源地址中文在线 | 国产精品沙发午睡系列 | 亚洲区小说区激情区图片区 | 国产精品人妻一区二区三区四 | 日本一卡2卡3卡4卡无卡免费网站 国产一区二区三区影院 | 久久国产精品偷任你爽任你 | 在线播放免费人成毛片乱码 | 久久精品国产大片免费观看 | 伊人久久大香线蕉午夜 | 乱中年女人伦av三区 | 无码人妻av免费一区二区三区 | 免费中文字幕日韩欧美 | 人妻熟女一区 | 欧美丰满少妇xxxx性 | 少妇激情av一区二区 | 色一情一乱一伦一区二区三欧美 | 激情五月综合色婷婷一区二区 | 在线天堂新版最新版在线8 | 精品无码国产一区二区三区av | 少妇高潮喷潮久久久影院 | 免费观看激色视频网站 | 国产熟妇另类久久久久 | 国产精品va在线观看无码 | 婷婷综合久久中文字幕蜜桃三电影 | 麻豆精品国产精华精华液好用吗 | 丝袜美腿亚洲一区二区 | 日日天日日夜日日摸 | 狂野欧美性猛xxxx乱大交 | 久久国产精品二国产精品 | 亚洲另类伦春色综合小说 | 国产精品.xx视频.xxtv | 99久久精品日本一区二区免费 | ass日本丰满熟妇pics | 国产精品久久久久久久影院 | 人妻熟女一区 | 精品无码国产一区二区三区av | 正在播放老肥熟妇露脸 | 国产成人无码区免费内射一片色欲 | 精品久久久无码中文字幕 | 日韩精品无码免费一区二区三区 | 伊在人天堂亚洲香蕉精品区 | 国産精品久久久久久久 | 亚洲一区二区三区播放 | 青青草原综合久久大伊人精品 | 强辱丰满人妻hd中文字幕 | 女人高潮内射99精品 | 国产精品久久久午夜夜伦鲁鲁 | 亚洲成a人片在线观看无码3d | 奇米影视7777久久精品 | 亚洲精品国产精品乱码不卡 | av人摸人人人澡人人超碰下载 | 99久久精品日本一区二区免费 | 真人与拘做受免费视频 | 男女超爽视频免费播放 | 亚洲精品一区二区三区在线观看 | 无码av最新清无码专区吞精 | 欧美三级a做爰在线观看 | 亚洲精品无码人妻无码 | 久久久久久久久888 | 色综合久久久无码中文字幕 | 又大又紧又粉嫩18p少妇 | 熟妇人妻中文av无码 | 亚洲精品一区三区三区在线观看 | 青青久在线视频免费观看 | 国产成人无码av片在线观看不卡 | 国产特级毛片aaaaaaa高清 | 性欧美牲交在线视频 | 国内丰满熟女出轨videos | 丰满肥臀大屁股熟妇激情视频 | 婷婷五月综合缴情在线视频 | 国产精品美女久久久网av | 377p欧洲日本亚洲大胆 | 又大又紧又粉嫩18p少妇 | 精品无码国产自产拍在线观看蜜 | 精品欧洲av无码一区二区三区 | 中文字幕人妻无码一夲道 | 久久亚洲精品中文字幕无男同 | 国产精品无码一区二区三区不卡 | 亚洲经典千人经典日产 | 成人无码视频在线观看网站 | 中文亚洲成a人片在线观看 | av无码久久久久不卡免费网站 | 在线观看免费人成视频 | 精品一区二区不卡无码av | 亚洲精品一区二区三区在线 | 精品久久久久香蕉网 | 亚洲成色在线综合网站 | 东京热无码av男人的天堂 | av无码电影一区二区三区 | 曰本女人与公拘交酡免费视频 | 人人澡人人妻人人爽人人蜜桃 | 女人被男人爽到呻吟的视频 | 东京无码熟妇人妻av在线网址 | 国产av久久久久精东av | 免费无码肉片在线观看 | 国产热a欧美热a在线视频 | 一本大道伊人av久久综合 | 十八禁视频网站在线观看 | 欧美成人午夜精品久久久 | 97资源共享在线视频 | 亚洲午夜久久久影院 | 国产黄在线观看免费观看不卡 | 国产性猛交╳xxx乱大交 国产精品久久久久久无码 欧洲欧美人成视频在线 | 在教室伦流澡到高潮hnp视频 | 未满小14洗澡无码视频网站 | 在线播放无码字幕亚洲 | 亚洲伊人久久精品影院 | 久久久久亚洲精品中文字幕 | 亚洲精品久久久久久久久久久 | 欧美真人作爱免费视频 | 131美女爱做视频 | 亚洲精品国产精品乱码视色 | 精品国产麻豆免费人成网站 | 久久精品国产日本波多野结衣 | 精品熟女少妇av免费观看 | 鲁大师影院在线观看 | 男人和女人高潮免费网站 | 人人妻人人澡人人爽人人精品 | 亚洲最大成人网站 | 色一情一乱一伦 | 精品久久8x国产免费观看 | 日本xxxx色视频在线观看免费 | 欧美老熟妇乱xxxxx | 亚洲无人区午夜福利码高清完整版 | 欧美精品一区二区精品久久 | 国产高清av在线播放 | 亚洲精品鲁一鲁一区二区三区 | 捆绑白丝粉色jk震动捧喷白浆 | 99久久婷婷国产综合精品青草免费 | 又粗又大又硬又长又爽 | 无码精品人妻一区二区三区av | 妺妺窝人体色www婷婷 | 少妇高潮喷潮久久久影院 | 免费中文字幕日韩欧美 | 亚洲国产精品一区二区美利坚 | 初尝人妻少妇中文字幕 | 久久久中文字幕日本无吗 | 色婷婷综合中文久久一本 | 国模大胆一区二区三区 | 国内精品人妻无码久久久影院 | 在线观看免费人成视频 | 人妻少妇精品无码专区二区 | 秋霞成人午夜鲁丝一区二区三区 | 国产色在线 | 国产 | 蜜桃无码一区二区三区 | 一本久道久久综合婷婷五月 | 成人无码视频在线观看网站 | 一本久道久久综合狠狠爱 | 久久亚洲a片com人成 | 国产精品手机免费 | 久久久久久久久888 | 国产激情综合五月久久 | 精品欧美一区二区三区久久久 | 精品成在人线av无码免费看 | 一本久道高清无码视频 | 狂野欧美性猛交免费视频 | 99久久人妻精品免费一区 | 秋霞特色aa大片 | 久久无码人妻影院 | 99riav国产精品视频 | 精品夜夜澡人妻无码av蜜桃 | 麻豆精产国品 | 四虎国产精品一区二区 | 久久天天躁狠狠躁夜夜免费观看 | 蜜桃无码一区二区三区 | 欧美亚洲日韩国产人成在线播放 | 无码播放一区二区三区 | 亚洲精品久久久久久久久久久 | 性做久久久久久久免费看 | aⅴ亚洲 日韩 色 图网站 播放 | 亚洲男女内射在线播放 | 2019nv天堂香蕉在线观看 | 国产午夜亚洲精品不卡下载 | 欧美日韩在线亚洲综合国产人 | 成人免费视频在线观看 | 亚洲小说图区综合在线 | 精品久久久无码中文字幕 | 曰韩少妇内射免费播放 | 少妇性荡欲午夜性开放视频剧场 | 色综合久久久久综合一本到桃花网 | 亚洲欧美日韩国产精品一区二区 | 亚洲欧美日韩国产精品一区二区 | 欧洲精品码一区二区三区免费看 | 蜜桃臀无码内射一区二区三区 | 成人一在线视频日韩国产 | 在线欧美精品一区二区三区 | 国产欧美精品一区二区三区 | 97se亚洲精品一区 | 亚洲精品国偷拍自产在线麻豆 | 男人的天堂2018无码 | 国产精品va在线播放 | 正在播放东北夫妻内射 | 人妻天天爽夜夜爽一区二区 | 欧美 日韩 亚洲 在线 | 国产精品va在线播放 | 露脸叫床粗话东北少妇 | 亚洲人成网站色7799 | 国产精品欧美成人 | 无码国产乱人伦偷精品视频 | 成年女人永久免费看片 | 亚洲国产精品久久久久久 | 东京无码熟妇人妻av在线网址 | 亚洲熟女一区二区三区 | 人人妻人人澡人人爽欧美精品 | 亚洲欧美色中文字幕在线 | 亚洲精品www久久久 | 中文字幕精品av一区二区五区 | 亚洲aⅴ无码成人网站国产app | 无码人妻精品一区二区三区下载 | 成人精品天堂一区二区三区 | 无码人妻黑人中文字幕 | 东京无码熟妇人妻av在线网址 | 国产精品久久久久久久影院 | 亚洲日韩乱码中文无码蜜桃臀网站 | 国产深夜福利视频在线 | 国产成人无码午夜视频在线观看 | 国产美女极度色诱视频www | 欧美日本免费一区二区三区 | 熟妇人妻中文av无码 | 国产精品亚洲а∨无码播放麻豆 | 中文字幕乱码中文乱码51精品 | 在线播放无码字幕亚洲 | 欧美精品国产综合久久 | 精品成在人线av无码免费看 | 无码精品人妻一区二区三区av | 又粗又大又硬毛片免费看 | 亚洲男人av香蕉爽爽爽爽 | 国产内射爽爽大片视频社区在线 | 国产农村妇女高潮大叫 | 中国女人内谢69xxxx | 强奷人妻日本中文字幕 | 国产精品沙发午睡系列 | 综合激情五月综合激情五月激情1 | 久青草影院在线观看国产 | 无码人妻精品一区二区三区不卡 | 图片小说视频一区二区 | 成人一在线视频日韩国产 | 精品午夜福利在线观看 | 人人爽人人澡人人人妻 | 人人妻在人人 | 国产成人精品一区二区在线小狼 | 精品无码一区二区三区爱欲 | 黄网在线观看免费网站 | 国产精品久久久久无码av色戒 | 欧美老人巨大xxxx做受 | 搡女人真爽免费视频大全 | 日韩亚洲欧美中文高清在线 | 99久久婷婷国产综合精品青草免费 | 国产精品18久久久久久麻辣 | 久久久无码中文字幕久... | 免费看男女做好爽好硬视频 | 少妇人妻av毛片在线看 | 亚无码乱人伦一区二区 | 人妻少妇精品无码专区动漫 | 日韩精品久久久肉伦网站 | 无遮挡国产高潮视频免费观看 | 国产在线aaa片一区二区99 | 久久99国产综合精品 | 伊人久久大香线蕉av一区二区 | 成熟妇人a片免费看网站 | 久久久久se色偷偷亚洲精品av | 亚洲日韩av一区二区三区四区 | 国产精品香蕉在线观看 | 国产9 9在线 | 中文 | 97色伦图片97综合影院 | 国产成人无码专区 | 亚洲熟妇色xxxxx欧美老妇y | 色婷婷香蕉在线一区二区 | 亚洲欧洲日本无在线码 | 欧洲精品码一区二区三区免费看 | 中文字幕人妻无码一夲道 | 精品少妇爆乳无码av无码专区 | 丰满少妇高潮惨叫视频 | 亚洲自偷自偷在线制服 | 亚洲伊人久久精品影院 | 婷婷五月综合缴情在线视频 | 欧美日韩视频无码一区二区三 | 国产又粗又硬又大爽黄老大爷视 | 熟妇人妻中文av无码 | 国产精品多人p群无码 | 乱中年女人伦av三区 | 色婷婷香蕉在线一区二区 | 国产成人一区二区三区别 | 久久精品国产大片免费观看 | 国产精品久免费的黄网站 | 国语自产偷拍精品视频偷 | 免费无码一区二区三区蜜桃大 | 久久午夜无码鲁丝片 | 久久aⅴ免费观看 | 日韩人妻无码一区二区三区久久99 | 巨爆乳无码视频在线观看 | 日日干夜夜干 | 国产无遮挡又黄又爽又色 | 国产精品igao视频网 | 久久国产精品二国产精品 | 国产内射爽爽大片视频社区在线 | 国产精品成人av在线观看 | 精品国偷自产在线 | 熟妇人妻无码xxx视频 | 无码人妻久久一区二区三区不卡 | 午夜男女很黄的视频 | 国产成人无码午夜视频在线观看 | 久久久久久久久蜜桃 | 丁香啪啪综合成人亚洲 | 内射老妇bbwx0c0ck | 日本一区二区三区免费播放 | 偷窥日本少妇撒尿chinese | 啦啦啦www在线观看免费视频 | 在线观看免费人成视频 | 狂野欧美性猛交免费视频 | 成年美女黄网站色大免费视频 | 欧美人与物videos另类 | 日韩精品一区二区av在线 | 亚洲成av人片在线观看无码不卡 | 最新版天堂资源中文官网 | 国产精品久久久久9999小说 | 欧美freesex黑人又粗又大 | 大地资源中文第3页 | 中文字幕av无码一区二区三区电影 | 欧美 亚洲 国产 另类 | 少妇一晚三次一区二区三区 | 色偷偷av老熟女 久久精品人妻少妇一区二区三区 | 97无码免费人妻超级碰碰夜夜 | 精品人妻中文字幕有码在线 | 国产精品美女久久久 | 2019nv天堂香蕉在线观看 | 无码帝国www无码专区色综合 | 老熟女乱子伦 | 日韩精品无码免费一区二区三区 | 亚洲国产欧美在线成人 | 精品乱子伦一区二区三区 | 人妻aⅴ无码一区二区三区 | 国内揄拍国内精品少妇国语 | 久久人人97超碰a片精品 | 久久99精品久久久久婷婷 | 国产精品香蕉在线观看 | 中文字幕无码人妻少妇免费 | 男女爱爱好爽视频免费看 | 在线亚洲高清揄拍自拍一品区 | 亚洲中文字幕乱码av波多ji | 亚洲乱码国产乱码精品精 | 国产精品久久久久久亚洲毛片 | 在线欧美精品一区二区三区 | 无码人妻精品一区二区三区不卡 | 国产一精品一av一免费 | 无码午夜成人1000部免费视频 | 国产sm调教视频在线观看 | 老太婆性杂交欧美肥老太 | 久久国产劲爆∧v内射 | 爽爽影院免费观看 | 色爱情人网站 | 高清国产亚洲精品自在久久 | 人妻少妇精品无码专区二区 | 国産精品久久久久久久 | 最新国产麻豆aⅴ精品无码 | 欧美成人午夜精品久久久 | 激情爆乳一区二区三区 | 美女黄网站人色视频免费国产 | 日韩精品a片一区二区三区妖精 | 精品国产精品久久一区免费式 | 俺去俺来也在线www色官网 | 日本护士xxxxhd少妇 | 国产精品第一区揄拍无码 | 麻豆人妻少妇精品无码专区 | 亚洲日本va午夜在线电影 | 免费人成在线观看网站 | 丝袜足控一区二区三区 | 水蜜桃色314在线观看 | 亚洲日本va午夜在线电影 | 成人免费视频在线观看 | 亚洲色在线无码国产精品不卡 | 亚洲乱码日产精品bd | 国产成人综合色在线观看网站 | 日韩精品无码免费一区二区三区 | 九九热爱视频精品 | www国产亚洲精品久久久日本 | 日本熟妇人妻xxxxx人hd | 欧美日韩一区二区免费视频 | 色一情一乱一伦一视频免费看 | 国产精品美女久久久久av爽李琼 | 国产精品va在线播放 | 久在线观看福利视频 | 国产精品久久久久久亚洲影视内衣 | 啦啦啦www在线观看免费视频 | 中文毛片无遮挡高清免费 | 国产亚洲精品精品国产亚洲综合 | 精品久久8x国产免费观看 | 乌克兰少妇性做爰 | 国产精品美女久久久久av爽李琼 | 伊人久久大香线焦av综合影院 | 成人欧美一区二区三区黑人免费 | 国产成人精品一区二区在线小狼 | 久激情内射婷内射蜜桃人妖 | 国产免费无码一区二区视频 | 高潮毛片无遮挡高清免费视频 | 欧洲vodafone精品性 | 婷婷六月久久综合丁香 | 欧洲极品少妇 | 亚洲 a v无 码免 费 成 人 a v | 欧美精品在线观看 | 水蜜桃色314在线观看 | 色一情一乱一伦一视频免费看 | 精品久久久久香蕉网 | 麻豆人妻少妇精品无码专区 | 国产精品久久久 | 亚洲人成影院在线无码按摩店 | 成年美女黄网站色大免费视频 | 亚洲一区二区三区无码久久 | 免费观看的无遮挡av | 女人被爽到呻吟gif动态图视看 | 亚洲 激情 小说 另类 欧美 | 亚洲色大成网站www | 成人免费无码大片a毛片 | 天干天干啦夜天干天2017 | 巨爆乳无码视频在线观看 | 亚洲国产精品美女久久久久 | 精品成人av一区二区三区 | 亚洲s码欧洲m码国产av | 红桃av一区二区三区在线无码av | 日韩av无码一区二区三区 | 丰满护士巨好爽好大乳 | 美女扒开屁股让男人桶 | 成人试看120秒体验区 | 一本久道久久综合婷婷五月 | 青青草原综合久久大伊人精品 | 日本饥渴人妻欲求不满 | 中文字幕 亚洲精品 第1页 | 日本护士xxxxhd少妇 | 国产午夜亚洲精品不卡下载 | 在线а√天堂中文官网 | 中文字幕日韩精品一区二区三区 | 亚洲区小说区激情区图片区 | 又湿又紧又大又爽a视频国产 | 久久久国产一区二区三区 | 亚洲 a v无 码免 费 成 人 a v | 18禁止看的免费污网站 | 激情内射亚州一区二区三区爱妻 | 娇妻被黑人粗大高潮白浆 | 国产性猛交╳xxx乱大交 国产精品久久久久久无码 欧洲欧美人成视频在线 | 伊人久久大香线蕉亚洲 | 国产综合色产在线精品 | 一区二区传媒有限公司 | 四虎影视成人永久免费观看视频 | 久久精品无码一区二区三区 | 亚洲va中文字幕无码久久不卡 | 小泽玛莉亚一区二区视频在线 | 国产精品久久久久久久9999 | 国产成人无码一二三区视频 | 日本爽爽爽爽爽爽在线观看免 | 97夜夜澡人人双人人人喊 | 无遮挡啪啪摇乳动态图 | 性欧美牲交在线视频 | 水蜜桃亚洲一二三四在线 | 国产免费无码一区二区视频 | 男女作爱免费网站 | 内射欧美老妇wbb | 青青久在线视频免费观看 | 日欧一片内射va在线影院 | 日本精品高清一区二区 | 十八禁真人啪啪免费网站 | 国产在线aaa片一区二区99 | 国产69精品久久久久app下载 | 欧美亚洲日韩国产人成在线播放 | 国产偷国产偷精品高清尤物 | 人妻与老人中文字幕 | 国产欧美精品一区二区三区 | 国产精品第一区揄拍无码 | 2020久久香蕉国产线看观看 | 日本熟妇人妻xxxxx人hd | 国产精品人妻一区二区三区四 | 日日橹狠狠爱欧美视频 | 国产午夜亚洲精品不卡 | 国产亚洲精品久久久久久久久动漫 | 人妻无码久久精品人妻 | 国产一区二区三区精品视频 | 亚洲成a人片在线观看无码3d | 水蜜桃亚洲一二三四在线 | 青青青手机频在线观看 | 亚洲精品久久久久avwww潮水 | 国产农村妇女高潮大叫 | 永久免费观看国产裸体美女 | 国产乱子伦视频在线播放 | 又色又爽又黄的美女裸体网站 | 日韩精品久久久肉伦网站 | 奇米综合四色77777久久 东京无码熟妇人妻av在线网址 | 成人欧美一区二区三区 | 无码精品人妻一区二区三区av | 国产精品久久国产精品99 | 国产香蕉尹人综合在线观看 | 国精品人妻无码一区二区三区蜜柚 | 国产午夜亚洲精品不卡下载 | 精品人妻人人做人人爽夜夜爽 | 中文字幕+乱码+中文字幕一区 | 欧美精品国产综合久久 | 正在播放老肥熟妇露脸 | 日本成熟视频免费视频 | 性欧美大战久久久久久久 | 性欧美熟妇videofreesex | 国产性生交xxxxx无码 | 人妻人人添人妻人人爱 | 亚洲无人区午夜福利码高清完整版 | 亚洲国产精品一区二区第一页 | 国产精品久久久久影院嫩草 | 国产激情无码一区二区app | 欧美熟妇另类久久久久久不卡 | 欧美性猛交xxxx富婆 | 亚洲精品一区二区三区大桥未久 | 国产亚洲精品久久久久久大师 | 日韩av无码一区二区三区不卡 | 俺去俺来也www色官网 | 在线a亚洲视频播放在线观看 | 野狼第一精品社区 | 动漫av一区二区在线观看 | 免费观看黄网站 | 国产精品免费大片 | 亚洲码国产精品高潮在线 | 水蜜桃色314在线观看 | 娇妻被黑人粗大高潮白浆 | 成人免费视频一区二区 | 国产成人综合色在线观看网站 | 国产农村乱对白刺激视频 | 老子影院午夜精品无码 | 亚洲第一无码av无码专区 | 麻豆国产丝袜白领秘书在线观看 | 乱码av麻豆丝袜熟女系列 | 亚洲精品中文字幕久久久久 | 漂亮人妻洗澡被公强 日日躁 | 成熟女人特级毛片www免费 | 亚洲熟妇色xxxxx亚洲 | 天下第一社区视频www日本 | 色综合久久久无码网中文 | 国产高清av在线播放 | 秋霞特色aa大片 | 久久久久免费看成人影片 | www国产精品内射老师 | 亚洲va中文字幕无码久久不卡 | 四虎国产精品一区二区 | 国产色视频一区二区三区 | 色欲av亚洲一区无码少妇 | 少妇人妻av毛片在线看 | 西西人体www44rt大胆高清 | 色偷偷人人澡人人爽人人模 | 在线视频网站www色 | 成人综合网亚洲伊人 | 强伦人妻一区二区三区视频18 | 夜夜影院未满十八勿进 | 人人爽人人澡人人人妻 | 中文字幕无码视频专区 | 亚洲精品成人av在线 | 欧美老人巨大xxxx做受 | 成人一在线视频日韩国产 | 成人精品视频一区二区三区尤物 | 欧美熟妇另类久久久久久多毛 | 亚洲无人区一区二区三区 | 狠狠色色综合网站 | 欧美日韩人成综合在线播放 | 黑人大群体交免费视频 | 亚洲综合伊人久久大杳蕉 | 无码国产色欲xxxxx视频 | 中文字幕乱码亚洲无线三区 | 国产内射老熟女aaaa | 中文字幕无码视频专区 | 成人一区二区免费视频 | 国产成人无码av一区二区 | 中文字幕日韩精品一区二区三区 | av无码电影一区二区三区 | 欧美三级a做爰在线观看 | 亚洲欧洲无卡二区视頻 | av无码久久久久不卡免费网站 | 国产真实伦对白全集 | 人妻互换免费中文字幕 | 欧美 丝袜 自拍 制服 另类 | 亚洲熟女一区二区三区 | 丝袜足控一区二区三区 | 人妻少妇被猛烈进入中文字幕 | 97夜夜澡人人双人人人喊 | 中文无码精品a∨在线观看不卡 | 无码国模国产在线观看 | 国产成人无码一二三区视频 | 一本久久a久久精品亚洲 | 欧美大屁股xxxxhd黑色 | 亚洲区小说区激情区图片区 | 性做久久久久久久免费看 | 999久久久国产精品消防器材 | 一本色道久久综合狠狠躁 | 亚洲精品一区二区三区四区五区 | 国产人妻久久精品二区三区老狼 | 亚洲色偷偷男人的天堂 | 狠狠色丁香久久婷婷综合五月 | 色偷偷人人澡人人爽人人模 | 丰满护士巨好爽好大乳 | 免费男性肉肉影院 | 亚洲精品午夜国产va久久成人 | 亚洲中文字幕无码一久久区 | 2020久久香蕉国产线看观看 | 蜜桃无码一区二区三区 | 波多野结衣乳巨码无在线观看 | 少妇的肉体aa片免费 | 亚洲人成人无码网www国产 | 麻豆蜜桃av蜜臀av色欲av | 亚洲自偷精品视频自拍 | 爱做久久久久久 | 秋霞成人午夜鲁丝一区二区三区 | 天天av天天av天天透 | 小sao货水好多真紧h无码视频 | 精品国产麻豆免费人成网站 | 国产sm调教视频在线观看 | 国产美女极度色诱视频www | 亚洲欧洲无卡二区视頻 | 精品久久综合1区2区3区激情 | 国产香蕉97碰碰久久人人 | 亚洲成av人片在线观看无码不卡 | 欧美丰满熟妇xxxx性ppx人交 | 男女下面进入的视频免费午夜 | 亚洲欧美日韩综合久久久 | а√天堂www在线天堂小说 | 蜜桃视频韩日免费播放 | 97无码免费人妻超级碰碰夜夜 | 在教室伦流澡到高潮hnp视频 | 噜噜噜亚洲色成人网站 | 欧美丰满熟妇xxxx | 久久久婷婷五月亚洲97号色 | 久久综合香蕉国产蜜臀av | 精品偷自拍另类在线观看 | 综合人妻久久一区二区精品 | 久久99热只有频精品8 | 精品熟女少妇av免费观看 | 日本熟妇乱子伦xxxx | 丰满少妇熟乱xxxxx视频 | 久久99精品国产麻豆蜜芽 | 67194成是人免费无码 | 国产精品人人妻人人爽 | 亚洲熟妇色xxxxx欧美老妇y | 无码人妻av免费一区二区三区 | 黑人巨大精品欧美一区二区 | 午夜肉伦伦影院 | 中文字幕色婷婷在线视频 | 国产人妻大战黑人第1集 | 久9re热视频这里只有精品 | 久久久精品国产sm最大网站 |