免费国产精品自在自线-91精品国产色综合久久久浪潮-99热久久免费频精品-国产精品国模在线观看-久久亚洲国产精品成人?V秋霞-久久国产一级A片免费播放-亚洲国产欧洲综合97久久-久久国产白嫩美女呻吟高潮

ARTICLE DETAIL

資訊詳情

深耕商務建站與企業(yè)官網運營的一線實戰(zhàn)洞察。

07-04-源碼-.NET Core GC清掃與壓縮

07-04-源碼-.NET Core GC清掃與壓縮 .NET Core GC 清掃與壓縮篇章07-源碼深度-.NET Core GC |閱讀時間約 45 分鐘一、引言標記階段識別了存活對象后GC 進入回收階段——清掃死亡對象、壓縮存活對象。清掃和壓縮是 GC 中內存效率的決定性因素清掃決定了多少死亡內存被真正釋放壓縮決定了碎片是否累積到影響分配的程度。但清掃和壓縮的代價也不容忽視。一次全堆壓縮可能耗時數十到數百毫秒直接反映在應用的暫停時間上。所以 .NET Core GC 的核心設計哲學是能不清壓就不清壓必須清壓時盡量并行化。這個哲學貫穿了從計劃決策到清掃實現、從壓縮策略到 LOH 特殊處理的每一個環(huán)節(jié)。在展開之前先把本章的定位說清楚。07-03 標記篇已經講完了哪些對象活著本章接著講活著的東西怎么擺回去、死的東西怎么收走。后臺 GC 的并發(fā)編排見 07-05分配路徑見 07-02堆結構與分代布局的背景見 07-01。二、計劃階段Plan Phase2.1 清掃前的決策GC 在執(zhí)行任何清掃動作之前必須先制定計劃。這個計劃決定了哪些代需要清掃、哪些代需要壓縮、LOH 是否需要特殊處理、是否啟用并行清掃。// gc.h - GCPlan 結構體簡化示意不含全部字段 struct GCPlan { bool compact_gen2; // Gen 2 是否需要壓縮 bool compact_loh; // LOH 是否需要壓縮 int sweep_gen0_segments; // Gen 0 需要清掃的段數 int sweep_gen1_segments; // Gen 1 需要清掃的段數 int sweep_gen2_segments; // Gen 2 需要清掃的段數 bool concurrent_sweep; // 是否并發(fā)清掃后臺 GC 時 bool parallel_sweep; // 是否并行清掃多核時 float fragmentation_ratio_gen2; // Gen 2 碎片率 float fragmentation_ratio_loh; // LOH 碎片率 };計劃階段的核心輸入是碎片率。碎片率定義為碎片率 1.0 - (最大連續(xù)空閑塊大小 / 總空閑內存)換句話說碎片率衡量的是空閑內存被分散到了多小的塊里。碎片率為 0 表示所有空閑內存連成一塊碎片率為 1 表示每個空閑塊都只有 1 字節(jié)極端情況。2.2 壓縮觸發(fā)條件壓縮不是每次 GC 都做的——它只在碎片率超過閾值時才觸發(fā)。.NET Core GC 的默認閾值因代而異代壓縮觸發(fā)閾值原因Gen 0不壓縮Gen 0 每次 GC 都重建天然無碎片Gen 1不壓縮Gen 1 是 Gen 0 的緩沖區(qū)本身不獨立管理Gen 2~50%大堆碎片累積快壓縮收益高LOH~70%手動LOH 不使用 bump pointer碎片率天然較低注意 Gen 0 和 Gen 1從不壓縮。這是因為 Gen 0 在每次 GC 時都會重建——所有存活對象晉升到 Gen 1Gen 0 的段被完全清空并重新使用。這種全量晉升 段復用的機制天然消除了 Gen 0 的碎片不需要壓縮。Gen 1 也不壓縮因為它不是一個獨立的內存區(qū)域——它和 Gen 2 共享同一組段。對 Gen 2 的壓縮同時就是對 Gen 1 的壓縮。2.3 計劃決策的時序標記階段完成 │ ▼ 統(tǒng)計各代碎片率 │ ├─ Gen 2 碎片率 50%? │ └─ Yes → compact_gen2 true │ ├─ LOH 手動觸發(fā)壓縮? │ └─ Yes → compact_loh true │ ├─ 并發(fā) GC 且 Gen 2 需要清掃? │ └─ Yes → concurrent_sweep true │ └─ CPU 核數 1 且需要清掃? └─ Yes → parallel_sweep true計劃階段本身非??焱ǔV恍鑾装傥⒚?。它的輸出GCPlan會被傳遞給清掃階段和壓縮階段指導后續(xù)的所有操作。三、清掃階段Sweep Phase3.1 清掃的基本原理清掃是 GC 回收階段的第一步。它的任務很簡單遍歷段中的所有對象把死亡對象的內存標記為可用。但實現起來并不簡單。清掃需要處理以下問題對象遍歷如何高效地遍歷段中的所有對象死亡檢測如何判斷一個對象是否死亡空閑管理如何管理回收后的空閑內存3.1.1 對象遍歷清掃遍歷段的方式與標記遍歷對象圖的方式不同。標記是從根出發(fā)沿著引用字段下鉆而清掃是順序遍歷段中的每個對象按對象大小步進。// SweepSegment 核心邏輯簡化示意 void SweepSegment(heap_segment* seg) { uint8_t* current seg-start; uint8_t* end seg-allocated; while (current end) { Object* obj (Object*)current; // 檢查對象是否被標記 if (!obj-IsMarked()) { // 死亡對象回收其內存 size_t size obj-GetSize(); AddToFreeList(current, size); } else { // 存活對象清除標記位準備下一輪 obj-ClearMark(); } // 按對象大小步進到下一個對象 current obj-GetSize(); } }這個遍歷是順序的對內存的訪問模式非常友好——CPU 預取器可以很好地工作緩存命中率極高。這也是為什么清掃階段通常只占 GC 暫停時間的 10% 左右。3.1.2 死亡檢測死亡檢測通過檢查對象的標記位mark bit實現。標記階段會為每個存活對象設置標記位清掃階段只需檢查這個位標記位為 1存活對象清除標記位繼續(xù)下一個標記位為 0死亡對象回收內存標記位通常存儲在對象頭的某個比特位中訪問速度極快一條位操作指令。3.1.3 空閑管理回收后的空閑內存需要被管理以便后續(xù)分配能夠快速找到可用空間。.NET Core GC 使用按大小分類的空閑列表size-class free list空閑列表結構 ┌─────────────────────────────────────────────────┐ │ FreeList[0] (8-15 字節(jié)) ──? [塊A] ──? [塊B] │ │ FreeList[1] (16-31 字節(jié)) ──? [塊C] ──? NULL │ │ FreeList[2] (32-63 字節(jié)) ──? [塊D] │ │ ... │ │ FreeList[N] (8KB) ──? [塊E] ──? [塊F] │ └─────────────────────────────────────────────────┘空閑列表按大小分類的好處是分配時可以根據請求大小直接定位到對應的鏈表避免全表搜索。這與 slab 分配器的思想類似——將相近大小的空閑塊歸為一類每類維護一個獨立鏈表。3.2 清掃的零分配保證清掃階段有一個重要的設計原則不分配任何新對象。所有需要的臨時數據結構空閑鏈表節(jié)點等都從已回收的對象本身借用內存。這是經典的intrusive list侵入式鏈表技術被回收的對象內存直接作為鏈表節(jié)點使用不需要額外分配內存來維護空閑列表。具體來說死亡對象的第一個字段原本存儲方法表指針之后的位置被覆寫為下一個空閑塊的指針。死亡對象回收前的內存布局 ┌────────────────────────────────────────────┐ │ 方法表指針 (8B) │ 同步塊 (8B) │ 字段數據... │ └────────────────────────────────────────────┘ │ ▼ 回收后方法表指針之后的內存被覆寫 ┌────────────────────────────────────────────┐ │ 方法表指針 (8B) │ 空閑鏈表指針 ?────────────┘ │ (保持不變GC 不再需要) │ └────────────────────────────────────────────┘這種設計的優(yōu)勢零額外內存不需要為空閑鏈表分配任何額外內存。零額外分配不需要在清掃過程中調用malloc或new。零額外開銷空閑鏈表的插入操作只是修改一個指針。不清零被回收的對象不需要清零因為它的內存即將被重新分配使用。3.3 并發(fā)清掃在后臺 GCBackground GC模式下清掃可以與應用線程并發(fā)執(zhí)行。這是 .NET Core 3.0 的重要優(yōu)化時間線示意 應用線程: [Alloc][Alloc][Alloc][Alloc][Alloc][Alloc]... │ │ GC線程: ──[標記 Gen2]──[清掃 Gen2]──────[壓縮 Gen2]── │ │ │ │ ├─ 并發(fā)清掃應用線程繼續(xù)分配 │ └─ 壓縮時需要 STW并發(fā)清掃的關鍵技術是標記-清掃并發(fā)標記階段在后臺線程中并行執(zhí)行清掃階段在標記完成后立即開始不需要等待應用線程全部掛起。只有壓縮階段需要 STWStop-The-World。并發(fā)清掃的實現依賴于以下機制標記位的原子操作標記階段設置標記位使用原子操作清掃階段讀取標記位不需要加鎖。段級鎖清掃器獲取段的鎖后其他線程不能修改該段的內容。段級鎖的粒度比全局鎖小得多減少了競爭。卡片表補償并發(fā)期間應用線程可能創(chuàng)建新的引用這些引用通過卡片表記錄清掃完成后由 GC 進行補償掃描。3.4 并行清掃在多核機器上清掃可以并行化。不同清掃器線程負責不同的段互不干擾段 0 ──? 清掃器線程 0 段 1 ──? 清掃器線程 1 段 2 ──? 清掃器線程 2 段 3 ──? 清掃器線程 3并行清掃的加速比接近線性——4 核機器上清掃 4 個段的耗時約等于清掃 1 個段的 4 倍。但并行清掃也有開銷任務分發(fā)需要將段分配給清掃器線程這本身有同步開銷??臻e列表合并各線程回收的空閑塊需要合并到全局空閑列表中。緩存競爭多個線程同時寫入空閑列表可能導致緩存行失效。因此并行清掃在段數較多時收益明顯段數較少時可能得不償失。.NET Core GC 會根據段數和 CPU 核數自動決定是否啟用并行清掃。四、壓縮階段Compact Phase4.1 為什么需要壓縮清掃雖然回收了死亡對象的內存但它留下的空閑塊是分散的。如果死亡對象和存活對象交替出現空閑塊也會交替出現清掃前的段布局 ┌──────┬────────┬──────┬────────┬──────┬────────┬──────┐ │ 存活 │ 死亡 │ 存活 │ 死亡 │ 存活 │ 死亡 │ 存活 │ │ ObjA │ ObjX │ ObjB │ ObjY │ ObjC │ ObjZ │ ObjD │ └──────┴────────┴──────┴────────┴──────┴────────┴──────┘ 空閑塊: [ObjX] [ObjY] [ObjZ] 分散在存活對象之間 清掃后未壓縮 ┌──────┬────────┬──────┬────────┬──────┬────────┬──────┬──────┐ │ 存活 │ 死亡 │ 存活 │ 死亡 │ 存活 │ 死亡 │ 存活 │ 空閑 │ │ ObjA │ ObjX │ ObjB │ ObjY │ ObjC │ ObjZ │ ObjD │ │ └──────┴────────┴──────┴────────┴──────┴────────┴──────┴──────┘ 空閑塊分散在 ObjA/ObjB/ObjC/ObjD 之間 → 碎片化 壓縮后 ┌──────┬──────┬──────┬──────┬──────────────────────────────┐ │ 存活 │ 存活 │ 存活 │ 存活 │ 連續(xù)空閑空間 │ │ ObjA │ ObjB │ ObjC │ ObjD │ (可分配區(qū)域) │ └──────┴──────┴──────┴──────┴──────────────────────────────┘ 所有存活對象移到段開頭空閑空間集中在段尾 → 無碎片壓縮的核心價值是將分散的空閑塊合并為連續(xù)的可用空間。沒有壓縮碎片會逐步累積最終導致即使總空閑內存足夠也無法分配大塊對象因為找不到足夠大的連續(xù)空間。4.2 壓縮的三個步驟壓縮是 GC 中最復雜的操作涉及三個緊密耦合的步驟步驟 1計算新地址// ComputeNewAddresses簡化示意 void ComputeNewAddresses(int generation) { uint8_t* write_ptr segment-start; // 寫入指針從段頭開始 for (uint8_t* current segment-start; current segment-allocated; current obj-GetSize()) { Object* obj (Object*)current; if (obj-IsMarked()) { // 存活對象記錄新地址 obj-SetNewAddress(write_ptr); write_ptr obj-GetSize(); } // 死亡對象跳過不分配新地址 } segment-allocated write_ptr; // 更新段的分配上限 }這一步是純讀取 順序寫入對內存的訪問模式非常友好。每個存活對象只被訪問一次按順序從段頭掃到段尾。關鍵細節(jié)新地址單調遞增存活對象按原順序排列新地址嚴格遞增。這意味著壓縮不會改變對象的相對順序有利于緩存局部性。死亡對象被跳過死亡對象不占用新地址空間相當于在計算新地址的同時完成了收縮。對象大小不變壓縮不改變對象大小只改變對象的起始地址。步驟 2修復引用Fix References// FixReferences簡化示意 void FixReferences(int generation) { // 修復棧上的引用 for (Thread* thread : suspended_threads) { for (RefLocation ref : thread-stack_references) { if (ref.target segment_start ref.target segment_end) { *ref.location ref.target-GetNewAddress(); } } } // 修復堆上的引用存活對象中的引用字段 for (uint8_t* obj segment-start; obj segment-allocated; ) { if (obj-IsMarked()) { obj-FixReferences(); // 對象內部的引用字段全部更新 obj obj-GetSize(); } } // 修復靜態(tài)字段 for (StaticRef ref : static_references) { if (ref.target segment_start ref.target segment_end) { *ref.location ref.target-GetNewAddress(); } } // 修復句柄表 for (HandleEntry entry : handle_table) { if (entry.target segment_start entry.target segment_end) { entry.target entry.target-GetNewAddress(); } } }引用修復是壓縮中最復雜、最耗時的部分。需要修復的引用來源包括棧引用各線程棧幀中指向壓縮段的對象引用。堆引用存活對象內部的引用字段指向同一段或其他段中的對象。靜態(tài)字段類靜態(tài)變量中指向壓縮段的引用。句柄表GCHandle 中指向壓縮段的引用。GC 內部結構如卡片表、根表等。引用修復的關鍵約束必須在復制之前完成。因為復制會移動對象如果先復制再修復引用修復時找不到舊地址。步驟 3復制對象數據// CopyObjects簡化示意 void CopyObjects(int generation) { for (uint8_t* current segment-start; current segment-old_allocated; current obj-GetSize()) { Object* obj (Object*)current; if (obj-IsMarked()) { uint8_t* new_addr obj-GetNewAddress(); if (current ! new_addr) { // 對象需要移動復制數據 size_t size obj-GetSize(); MemMove(new_addr, current, size); } } } }復制階段使用MemMove批量移動對象數據。由于對象是按順序處理的且新地址也是順序遞增的MemMove的調用可以很好地利用 CPU 的 DMA 緩存行預取和 SIMD 指令。關鍵優(yōu)化原地跳過如果對象的新地址等于舊地址通常發(fā)生在段尾部的存活對象直接跳過不復制。批量復制MemMove內部使用 SIMD 指令如 AVX2一次復制 32 或 64 字節(jié)比逐字節(jié)復制快數倍。寫合并多個小對象的復制可以合并為一次MemMove調用減少函數調用開銷。4.3 壓縮的代價壓縮涉及大量內存復制和引用更新是 GC 中最耗時的操作。以下是一個典型場景的耗時分解100MB Gen 2 堆碎片率 60%一次全量壓縮 步驟 耗時 占比 ───────────────────────────────────── 計算新地址 5-10ms ~15% 修復引用 20-80ms ~60% ← 最耗時 復制對象數據 5-10ms ~15% 清理段元數據 1-2ms ~5% ───────────────────────────────────── 合計 30-100ms 100%各步驟的耗時特征計算新地址O(n) 順序遍歷緩存友好耗時與存活對象數成正比。修復引用O(n r)n 為存活對象數r 為引用字段總數。引用字段越多耗時越長。棧引用和句柄表引用的修復需要逐個處理無法批量優(yōu)化。復制對象數據O(n)但MemMove的常數極小實際耗時通常低于引用修復。清理段元數據O(1) 或 O(段數)耗時可忽略。4.4 壓縮的并發(fā)化.NET Core GC 在 .NET 6 中引入了并發(fā)壓縮的部分優(yōu)化。核心思想是將壓縮拆分為多個階段其中計算新地址和修復引用可以在后臺線程中并行執(zhí)行只有最后的復制 最終引用修復需要 STW。傳統(tǒng)壓縮全 STW [計算新地址][修復引用][復制對象][最終修復] ← 全部 STW 并發(fā)壓縮.NET 6 [計算新地址]──[修復引用] ← 后臺線程并行執(zhí)行 │ ▼ STW 切換點 [復制對象][最終修復] ← 短 STW這種設計的優(yōu)勢是將 STW 時間從幾十毫秒降低到幾毫秒。后臺階段雖然也消耗 CPU 和內存帶寬但不影響應用線程只有最后的 STW 階段會暫停應用。五、LOH 清掃與壓縮5.1 LOH 為什么不同LOH大對象堆的清掃和壓縮與 SOH小對象堆有本質區(qū)別原因在 07-02 中已經提到過不使用 bump pointerLOH 使用空閑列表管理天然不存在清掃后合并空閑塊的需求。對象生命周期長LOH 對象通常存活整個應用生命周期碎片率增長緩慢。壓縮代價極高LOH 對象可能從 85KB 到幾 GB復制一個大對象的代價相當于復制成千上萬個小對象。5.2 LOH 清掃LOH 的清掃與 SOH 類似也是遍歷死亡對象并回收內存。但由于 LOH 對象數量遠少于 SOH 對象LOH 清掃的耗時通??梢院雎圆挥?。// LOH Sweep簡化示意 void SweepLOH() { for (auto entry : loh_free_list) { if (!entry.obj-IsMarked()) { // 死亡 LOH 對象回收 AddToLOHFreeList(entry.obj, entry.size); } else { // 存活 LOH 對象清除標記 entry.obj-ClearMark(); } } }5.3 LOH 壓縮LOH 壓縮是一個手動觸發(fā)的操作默認不自動執(zhí)行。這是因為 LOH 壓縮的代價極高——它需要移動所有存活的大對象并更新所有指向它們的引用。// 手動觸發(fā) LOH 壓縮 GCSettings.LargeObjectHeapCompactionMode GCLargeObjectHeapCompactionMode.CompactOnce; // 下一次 GC.Collect() 會壓縮 LOH GC.Collect();LOH 壓縮的觸發(fā)條件觸發(fā)方式條件說明手動觸發(fā)GCSettings.LargeObjectHeapCompactionMode CompactOnce下一次 GC.Collect() 觸發(fā)永久模式GCSettings.LargeObjectHeapCompactionMode CompactEveryTime每次 GC.Collect() 都觸發(fā)不推薦自動觸發(fā)無.NET Core 默認不自動壓縮 LOHLOH 壓縮的代價內存復制所有存活 LOH 對象需要被移動復制量可能達到數 GB。引用更新所有指向 LOH 對象的引用需要更新包括棧引用、堆引用、靜態(tài)字段、句柄表。STW 時間長LOH 壓縮通常需要 STW 數百毫秒到數秒取決于 LOH 大小和存活對象數。因此LOH 壓縮應該謹慎使用只在確實存在嚴重碎片問題且影響分配時才觸發(fā)。5.4 LOH 碎片問題與緩解LOH 碎片是 .NET 中一個經典問題。當頻繁分配和釋放大小不一的 LOH 對象時空閑列表會逐漸碎片化最終導致即使總空閑內存足夠也無法分配新的大對象。緩解 LOH 碎片的策略避免頻繁分配/釋放 LOH 對象使用對象池復用 LOH 對象??刂茖ο蟠笮”M量使對象大小低于 85,000 字節(jié)閾值使其走 SOH 路徑。定期手動壓縮在低峰期手動觸發(fā) LOH 壓縮。使用ArrayPoolT對于數組類型的 LOH 對象使用數組池復用。六、壓縮的代價與觸發(fā)策略6.1 壓縮耗時分解一次完整的 Gen 2 壓縮100MB 堆的耗時構成Full GC 耗時分解100MB 堆碎片率 60% 標記: ████████████████████████ 60% (15-30ms) ← 后臺GC改造目標 清掃: ████ 10% (2-5ms) 壓縮: ██████ 30% (10-50ms) ← 最慢但僅在碎片率超閾值時觸發(fā) ───────────────────────────────────────────────── 合計: 100% (27-85ms)關鍵觀察標記占大頭標記是耗時最長的階段也是后臺 GC 優(yōu)化的主要目標。清掃最穩(wěn)定清掃耗時波動最小因為它只依賴存活對象數與碎片率無關。壓縮最可變壓縮耗時波動最大從幾毫秒低碎片到數百毫秒高碎片 大堆。6.2 壓縮觸發(fā)策略.NET Core GC 的壓縮觸發(fā)策略可以概括為保守觸發(fā)按需壓縮。是否壓縮的決策邏輯 1. Gen 0? → 不壓縮每次 GC 都重建 2. Gen 1? → 不壓縮與 Gen 2 共享段隨 Gen 2 一起壓縮 3. Gen 2? ├─ 碎片率 50%? → Yes → 壓縮 └─ No → 不壓縮 4. LOH? ├─ 手動觸發(fā)? → Yes → 壓縮 └─ No → 不壓縮即使碎片率很高這個策略的核心考量壓縮的代價高壓縮需要移動對象、更新引用耗時可能遠超清掃。碎片不是最緊急的問題只要還有足夠大的連續(xù)空閑塊碎片不會導致分配失敗。預算機制優(yōu)先通過 budget 機制控制 GC 頻率比通過壓縮控制碎片更經濟。6.3 壓縮的替代方案在某些場景下壓縮不是最優(yōu)選擇。.NET Core GC 提供了以下替代方案段復用回收的段不還給操作系統(tǒng)留給下輪復用。這避免了還了再要的系統(tǒng)調用開銷??臻e列表優(yōu)化通過按大小分類的空閑列表提高小塊的分配命中率減少對新段的需求。晉升策略調優(yōu)調整對象晉升策略讓短命對象更快離開 Gen 0減少 Gen 0 的碎片累積。七、GC 耗時分解與優(yōu)化方向7.1 一次 Full GC 的完整耗時一次 Full GC100MB Gen 2 堆碎片率 40%的耗時構成 階段 耗時 是否 STW 可并發(fā) ───────────────────────────────────────────────── 掛起線程 1-5ms Yes 否 根掃描 1-3ms Yes 否 標記 Gen 0/1 5-10ms 部分 是后臺 標記 Gen 2 10-20ms 部分 是后臺 清掃 Gen 0 1-2ms 部分 是并發(fā) 清掃 Gen 1/2 2-5ms 部分 是并發(fā) 壓縮 Gen 2 10-30ms Yes 否 修復引用 5-20ms Yes 部分 恢復線程 1-3ms Yes 否 ───────────────────────────────────────────────── 總 STW 時間 20-60ms 總耗時含并發(fā) 30-100ms7.2 優(yōu)化方向基于耗時分解GC 優(yōu)化的優(yōu)先級如下減少標記耗時后臺 GC 已經將標記移到后臺進一步優(yōu)化空間有限。減少壓縮觸發(fā)通過 budget 自適應和晉升策略降低碎片率減少壓縮觸發(fā)頻率。減少 STW 時間并發(fā)壓縮.NET 6將大部分壓縮工作移到后臺進一步降低 STW 時間。減少清掃耗時清掃已經很快10%優(yōu)化空間有限。八、清掃和壓縮的時機選擇8.1 何時壓縮.NET Core GC 根據以下因素決定是否壓縮碎片率空閑空間分散度超過閾值時觸發(fā)壓縮。Gen 2 默認閾值約 50%LOH 默認不自動壓縮。最近一次壓縮的時間間隔避免頻繁壓縮。如果剛做過壓縮即使碎片率略有上升也不會立即再次壓縮。堆大小大堆壓縮的收益更大——碎片浪費的絕對空間更多壓縮后釋放的連續(xù)空間也更可觀。內存壓力當操作系統(tǒng)通知內存緊張時GC 可能降低壓縮閾值更積極地壓縮以釋放空間。8.2 實際項目中的觀察在實際項目中大多數 GC 只需要清掃不需要壓縮。壓縮通常只在以下場景觸發(fā)長運行服務運行時間越長碎片累積越多壓縮觸發(fā)越頻繁。對象生命周期差異大如果同時存在短命對象和長命對象長命對象之間的空洞會逐步累積為碎片。LOH 頻繁分配雖然 LOH 不自動壓縮但 LOH 碎片會影響 Gen 2 的碎片率間接觸發(fā) Gen 2 壓縮。九、清掃的零分配保證9.1 Intrusive List 技術清掃階段有一個重要的設計原則不分配任何新對象。所有需要的臨時數據空閑鏈表節(jié)點等從已回收的對象本身借用內存。這是經典的intrusive list侵入式鏈表技術。具體來說被回收的死亡對象的內存被直接用作空閑鏈表的節(jié)點。死亡對象的第一個字段原本存儲方法表指針之后的位置被覆寫為下一個空閑塊的指針。這樣空閑鏈表不需要任何額外的內存分配——它寄生在已回收的對象內存上。死亡對象回收前的內存布局 ┌──────────────────────────────────────────────────────┐ │ 方法表指針 (8B) │ 同步塊 (8B) │ 字段數據 (N 字節(jié)) │ │ ← 對象頭 ← 對象數據 │ └──────────────────────────────────────────────────────┘ │ ▼ 回收后方法表指針之后的內存被覆寫為鏈表指針 ┌──────────────────────────────────────────────────────┐ │ 方法表指針 (8B) │ 空閑鏈表下一個節(jié)點指針 (8B) │ ... │ │ (GC 不再需要方法表指針) │ └──────────────────────────────────────────────────────┘ │ ▼ 插入空閑鏈表 FreeList[size_class] ──? [此塊] ──? [下一個空閑塊] ──? ...9.2 零分配的優(yōu)勢這種設計的優(yōu)勢是多方面的零額外內存不需要為空閑鏈表分配任何額外內存??臻e鏈表的節(jié)點就是死亡對象本身。零額外分配不需要在清掃過程中調用malloc或new避免了在 GC 過程中觸發(fā)遞歸 GC 的風險。零額外開銷空閑鏈表的插入操作只是修改一個指針時間復雜度 O(1)。不清零被回收的對象不需要清零。因為它的內存即將被重新分配使用清零是浪費。緩存友好空閑鏈表節(jié)點與對象數據在同一塊內存中訪問局部性好。9.3 與 Java GC 的對比Java 的 OpenJDK GC如 G1使用獨立的空閑列表結構每個空閑塊需要額外的元數據來記錄大小和下一個節(jié)點。這意味著清掃階段需要為每個死亡塊分配一個空閑節(jié)點。.NET 的 intrusive list 技術避免了這一開銷是零分配保證的關鍵。十、與 Unity GC 的對比10.1 Unity (SGen) 的清掃與壓縮Unity 的 GC 基于 Mono 的 SGenScavenge-Sweep Garbage Collector與 .NET Core GC 有顯著差異特性.NET Core GCUnity (SGen)清掃方式順序遍歷 intrusive list標記-清掃 獨立空閑列表壓縮策略Gen 2 按需壓縮分代壓縮Scavenge 階段LOH 壓縮手動觸發(fā)無專門 LOH并發(fā)清掃.NET 3.0 支持增量清掃可配置零分配保證清掃階段不分配部分支持壓縮暫停時間30-100ms100MB10-50ms100MBUnity 的增量清掃是應對移動設備資源限制的特殊設計——將清掃拆分成多個小片段避免單次清掃暫停過長。而 .NET Core GC 更傾向于一次性完成通過后臺 GC 和并發(fā)壓縮來降低單次暫停的代價。10.2 為什么 Unity 的壓縮暫停更短Unity SGen 的壓縮暫停通常比 .NET Core GC 短原因有三堆更小移動設備的堆通常只有幾十 MB而 .NET 服務端應用的堆可能達到數 GB。壓縮耗時與堆大小成正比。壓縮策略更保守SGen 只在必要時壓縮小代不壓縮整個堆。對象更小移動應用的對象通常較小復制代價更低。但這些差異也反映了平臺約束移動設備內存有限不能像服務端那樣使用大堆和 LOH。十一、量化數據的口徑說明11.1 數據性質本文給出的所有量化數據耗時、百分比、閾值等均為典型估算或示例量級非實測常數。實際數值取決于以下因素堆大小100MB 堆與 10GB 堆的耗時相差兩個數量級。碎片率碎片率從 10% 上升到 80%壓縮耗時可能增加 5-10 倍。CPU 核數并行清掃和壓縮的加速比接近線性但受內存帶寬限制。對象大小分布大對象多的堆壓縮耗時更長。引用密度引用字段多的對象修復耗時更長。11.2 典型場景參考以下數據基于 16 核 64GB 服務端場景的典型估算非實測場景Gen 0 耗時Gen 2 耗時是否壓縮低碎片 (20%)0.5-2ms10-30ms否中碎片 (20-50%)0.5-2ms20-60ms否高碎片 (50%)0.5-2ms50-150ms是LOH 壓縮N/A100-500ms是手動十二、總結與實踐建議12.1 核心要點回顧清掃和壓縮是 GC 回收階段的核心它們的設計體現了按需觸發(fā)、零分配保證、并發(fā)優(yōu)化的思想清掃回收死亡對象通過 intrusive list 技術實現零分配耗時僅占 GC 的 10%。壓縮消除碎片將分散的空閑塊合并為連續(xù)空間但代價高30% 的 GC 耗時。按需觸發(fā)壓縮只在碎片率超過閾值時觸發(fā)大多數 GC 只需清掃。并發(fā)優(yōu)化后臺 GC 將清掃移到后臺.NET 6 將壓縮的部分工作移到后臺。LOH 特殊處理LOH 不自動壓縮需要手動觸發(fā)代價極高。12.2 實踐建議基于對清掃和壓縮的理解以下是針對 C# 開發(fā)者的實踐建議理解壓縮觸發(fā)條件壓縮只在碎片率超過閾值時觸發(fā)。如果你的應用碎片率始終很低壓縮幾乎不會成為性能瓶頸。謹慎使用 LOH 壓縮GCSettings.LargeObjectHeapCompactionMode CompactOnce是核武器級別的操只在確實存在嚴重 LOH 碎片且影響分配時才使用。關注 Gen 2 堆大小Gen 2 堆越大壓縮耗時越長。通過減少長命對象的數量和大小可以降低壓縮耗時。避免對象生命周期混疊短命對象和長命對象混在一起會導致碎片快速累積??梢酝ㄟ^分層設計將短命和長命對象放在不同的類中來減少碎片。監(jiān)控碎片率使用 PerfView 或 ETW 事件監(jiān)控 GC 碎片率發(fā)現異常上升趨勢。理解零分配保證清掃階段不分配新對象所以不會觸發(fā)遞歸 GC。這意味著清掃的耗時是確定性的不會因 GC 嵌套而膨脹。12.3 清掃與壓縮的決策樹GC 回收階段 │ ├─ 標記階段完成 │ │ │ ├─ Gen 0? │ │ └─ 清掃重建段天然無碎片 │ │ │ ├─ Gen 1? │ │ └─ 清掃隨 Gen 2 一起處理 │ │ │ ├─ Gen 2? │ │ ├─ 碎片率 50%? │ │ │ ├─ Yes → 清掃 → 壓縮 │ │ │ └─ No → 清掃不壓縮 │ │ └─ 并發(fā)清掃? │ │ ├─ Yes → 后臺清掃 │ │ └─ No → STW 清掃 │ │ │ └─ LOH? │ ├─ 手動壓縮? │ │ ├─ Yes → 清掃 → 壓縮STW耗時高 │ │ └─ No → 清掃不壓縮 │ └─ 碎片率 70%? │ └─ 仍不自動壓縮LOH 壓縮代價過高十三、深入壓縮的引用修復細節(jié)13.1 引用修復的挑戰(zhàn)引用修復是壓縮階段最復雜的部分面臨以下挑戰(zhàn)引用來源多樣棧引用、堆引用、靜態(tài)字段、句柄表、GC 內部結構每種來源的修復方式不同。引用目標可能移動被引用的對象可能在同一段需要修復、在不同段不需要修復因為 GC 內部結構已經處理了跨段引用。修復順序必須先修復所有引用再移動對象數據。否則修復時找不到舊地址。13.2 棧引用的修復棧引用的修復是最直接的部分。在壓縮開始前所有應用線程被掛起GC 可以安全地掃描每個線程的棧幀// 棧引用修復簡化示意 void FixStackReferences(Thread* thread) { for (StackFrame* frame : thread-frames) { for (RefLocation ref : frame-local_variables) { if (ref.is_gc_ref ref.target_in_compressed_segment) { // 更新引用為新地址 *ref.location ref.target-GetNewAddress(); } } for (RefLocation ref : frame-parameters) { if (ref.is_gc_ref ref.target_in_compressed_segment) { *ref.location ref.target-GetNewAddress(); } } } }棧引用修復的關鍵點線程必須掛起修復棧引用時應用線程不能運行否則棧內容可能被改寫。寄存器也需要修復除了棧引用掛起時保存的寄存器快照中的引用也需要修復。修復是原地進行的直接修改棧幀中的引用值不需要移動棧本身。13.3 堆引用的修復堆引用的修復比棧引用復雜得多。存活對象內部的引用字段可能指向同一段中的任何對象也可能指向其他段。只有指向同一段的引用需要修復// 堆引用修復簡化示意 void FixHeapReferences(heap_segment* segment) { for (uint8_t* obj segment-start; obj segment-old_allocated; ) { if (obj-IsMarked()) { // 遍歷對象的引用字段 MethodTable* mt obj-GetMethodTable(); for (RefField* field : mt-reference_fields) { uint8_t* ref_addr obj field-offset; Object* target *(Object**)ref_addr; // 只修復指向同一段的引用 if (target segment-start target segment-end) { *(Object**)ref_addr target-GetNewAddress(); } } obj obj-GetSize(); } else { obj obj-GetSize(); // 死亡對象跳過 } } }堆引用修復的耗時取決于引用字段的數量。一個包含 10 個引用字段的對象修復時需要檢查 10 次、最多更新 10 次。對于引用字段多的對象如字典、列表修復耗時可能顯著高于簡單對象。13.4 句柄表的修復句柄表的修復相對簡單因為句柄表是一個集中管理的數據結構// 句柄表修復簡化示意 void FixHandleTable(heap_segment* segment) { for (HandleEntry entry : handle_table) { if (entry.target segment-start entry.target segment-end) { entry.target entry.target-GetNewAddress(); } } }句柄表的大小通常遠小于堆修復耗時可以忽略不計。但需要注意固定句柄pinned handle——固定句柄指向的對象在壓縮時不能被移動壓縮算法需要跳過這些對象。十四、深入壓縮算法的變體14.1 傳統(tǒng)壓縮移動對象前面描述的壓縮方式是移動對象將存活對象從舊地址復制到新地址。這是最常見的壓縮方式優(yōu)點是實現簡單、碎片消除徹底。但移動對象有一個問題指針不變性。如果外部代碼持有對象的原始指針如通過GCHandle的固定句柄移動對象會導致指針失效。這就是為什么固定句柄指向的對象不能被移動。14.2 間接壓縮更新指針另一種壓縮方式是不移動對象只更新引用。具體來說不移動任何對象數據。為每個對象維護一個轉發(fā)指針forwarding pointer指向壓縮后的邏輯位置。所有引用指向轉發(fā)指針而不是直接指向對象。傳統(tǒng)壓縮移動對象 舊地址: [ObjA][ObjB][ObjC] → 新地址: [ObjA][ObjB][ObjC][空閑] 引用 → ObjA 引用 → ObjA (新地址) 間接壓縮更新指針 舊地址: [ObjA][ObjB][ObjC] → 邏輯地址: [ObjA][ObjB][ObjC][空閑] 引用 → ObjA 引用 → 轉發(fā)指針 → ObjA (邏輯地址)間接壓縮的優(yōu)點是不需要移動對象數據缺點是引入了額外的間接尋址每次引用都需要多一次內存訪問。這在性能敏感的場景中是不可接受的所以 .NET Core GC 不使用這種方式。14.3 部分壓縮只壓縮熱點段還有一種優(yōu)化思路是只壓縮熱點段即分配最頻繁的段而不是壓縮整個代。這種部分壓縮的策略是識別熱點段分配最頻繁的段。只壓縮熱點段非熱點段保持原樣。非熱點段中的引用指向熱點段時通過 GC 內部結構進行間接尋址。這種方式的優(yōu)點是壓縮范圍小、耗時短缺點是實現復雜、間接尋址有性能開銷。.NET Core GC 目前不使用這種方式但在 .NET 7 中引入了更細粒度的段級壓縮優(yōu)化。十五、結語清掃和壓縮是 GC 回收階段的兩個核心操作它們共同決定了 GC 的內存效率和暫停時間。清掃通過 intrusive list 技術實現了零分配耗時穩(wěn)定且可預測壓縮通過移動對象和修復引用消除了碎片但代價較高。.NET Core GC 的設計哲學是能不清壓就不清壓必須清壓時盡量并行化。通過碎片率閾值、budget 自適應、后臺 GC、并發(fā)壓縮等技術.NET Core GC 在大多數場景下將壓縮的 STW 時間控制在幾毫秒到幾十毫秒之間。理解清掃和壓縮的機制有助于開發(fā)者寫出更友好的對象生命周期模式——減少碎片累積、降低壓縮觸發(fā)頻率、避免 LOH 碎片問題。在下一章中我們將深入后臺 GC 的實現07-05看看 .NET Core GC 如何將清掃和壓縮的耗時進一步攤薄到應用線程的分配間隙中。
返回列表
PREV
查看更多資訊
NEXT
返回資訊列表
97碰碰视频| 婷婷丁香人妻| 色婷婷内射| 婷婷综合色网| 狠狠88综合久久久久噜噜噜| 激情综合色五月六月婷婷| 五月婷婷无码| 婷婷五月天视| 五月婷导航| 激情视频综合| 午夜色婷婷| 另类小说五月天| 色综合久| 五月婷婷色啪| 婷婷六月激情丁香| 久久九九@| 99亚洲视频| 九九久久99| 亚洲欧美在线观看| 久月丁香爱婷婷综合| 狠狠va| 婷婷射丁香| 久久在这里99| 婷婷不卡基地| 天天日天天舔天天摸| www.久热| 在线日韩av| 99久久婷| 另类小说激情五月天| 丁香 久久| 五月天福利影院导航| 九九热在线99| 五月丁香婷婷激激激综合网色播| 国产67194| 99re资源在线视频导航| 一级操逼内射在线视频| 四川BBB搡BBB搡多人乱亂| 亭亭丁香97| 激情小说婷婷小说| 婷婷综合| 99'无码| 久久激情五月婷婷| 伊人久久大香蕉网| 婷婷五月丁香色综合| 无码AV免费精品一区二区三区| 成人av中文字幕| 天天综合网在线| 无码人妻AV久久久一区二区三区| 婷婷伊人激情婷婷| A短视频免费在线观看| 欧洲激情五月天婷婷| 超碰狠狠操| 亚洲成人在线五月天| 亚洲天堂99| 色婷婷五月丁香在线观看| 五月婷婷色| 深爱开心激情网| 99re思思久久| 天天舔夜夜操www com| WWW嗯嗯啊啊啊啊| 开心五月丁香婷婷| 五月天堂六月丁香亚州中文字幕久久| 激情五月,婷婷五月,丁香五月| 丁香婷婷六月| 丁香五月激动深爱欧美| 泰州成人视频| 婷婷六月综合在线| 国产激情在线观看| 色999亚洲人成色| 五月综合777| 9久操| 九九亚洲综合| 色天天综合色| 黄久久久| 少妇AB又爽又紧无码网站| 99热这里只有免费精品| 五月天婷婷色紫薇阁| AAA级久久久精品| 五月丁香婷婷激情在线| 婷婷亚洲综合| www.91AV.COM| 五月婷A V在线| 在线另类视频| 久久婷婷五月天蜜桃| 开心日韩丁香婷婷五月| 91久久1118| 婷婷九月激情| 色碰干| 性无码专区无码| 五月婷婷啪啪啪| 天天干天天操天天上| 啪啪五月综合| 日本天堂网站99| 中文字幕乱码亚洲精品一区| 可以免费观看的AV| 五月丁香网站| 综合色播| 日狠狠| 免费亚洲婷婷中文字幕| 1024日韩| Av大香蕉| 人妻久久久久久| 人人草开心五月天| 99精品丁香五月| 色综合久久久久| 婷婷在线播放| 丁香六月婷婷综合缴| 婷婷五月综合婷婷| 久热中文字幕在线线观看| 99久久精品色老| 九九色情网五月天| 久久一伦| 日本综合色色| 色婷婷丁香中文在线播放| 久久精品爱爱| 狠狠干.com| 五月天激情综合网| 美女视频图片久久91| 婷婷五月开心六月AV| 涩五月婷婷| 综合欧美五月婷婷| 丁香五月天色| 99热66| 成人AV中文字幕| 婷婷丁香18| 午夜激情婷婷| 超pen个人视频97| 婷婷五月超碰| 久久综合久色欧美综合狠狠| 中文字幕成人日韩| 色欲天天综合| 五丁香激情综合| 久久a热| 99综合久久| 99久视频| 精品亚洲日韩99欧美片| 这里只精品热在线18| 久久婷婷五月综合激情国产 | 去色色五月天| 狠狠色丁香久久婷婷综合五月| 亚洲AV综合网| 日本在线噜噜| 午夜天堂一区人妻| 欧美草久久五月天91| 深爱开心激情| 激情丁香五月天图片| 91人人爽狠狠狠| 日本五月婷婷久久久六月丁香| 天天天日天天天干| 五月天开心网| 国精产品一区一区三区免费视频| 91婷婷丁香五月| 一级片sese片.COM| 9热视频在线观看| 色婷婷六月| 亚州操逼网| VA国产在线综合网站| 伊人啪啪网| 久久综合九色综合97婷婷| 激情性爱网站| 99热亚洲精品| 91xxxx九色| av免费人人| 国产精品涩涩涩视频网站| 黄色91在线观看| 丁香六月婷婷色XXXX| 五月天婷婷婷| 婷婷性爱五月天| 无码91中文字幕| 99热成人精品| 五月丁香婷婷激情爱爱| 久久九九蜜| 中文字幕日产A片在线看| 青草青草久热这里只有精品| 伊人激情| 婷婷激情六月综合| 五月丁香网av| 9视频在线成人网站| 五月天色五月天| 超碰人人插| 婷婷婷婷色| 五月开心啪啪| 国产在线中文字幕| 热99热9| 久久婷视频| 五月色婷婷影院| AV在线观看网站| 色婷婷狠| 九九这里有精品| 五月丁香婷婷综合久久| 五月天五月色婷婷综合| 亚洲一区二区色图-亚洲精品国产精品乱码-成人AV | 九九视频免费| 依人大香蕉在钱1| 啄木鸟丝袜美女福利视频| 午夜福利8055| 另类丁香五月天区图| 99综合网| 深爱激情五月婷婷| 深爱激情AV| 丁香五月婷婷亚洲人| 黃色三级三级三级三级 qixing300.shrkbk.com www.jinbozs.com tianmiaosw.com | 欧美色色色色色色| 五月丁香亭亭A片| 亚洲av骚货| 99色丁香婷婷综合网| 99热www| 嫩草极品| 国产精品天天狠天天看| 亚洲激情在线| 狠狠干综合网| 丁香五月婷婷激情蜜桃| sisi热国产| www.无码com| 99热久久这里只有精品| 九九香蕉网| 婷婷丁香五月婷婷| 四色五月婷婷| 日韩三级高清无码| 玖玖资源站蜜臀| 天天草天天日| 激情五月婷婷色综合| 亚洲性受XXXX五月丁香| 激情综合五月天| 色五月天激情| 天天日天天做天天舔| 亚洲精品中文字幕成人片| 青青草大香| 日韩五月婷婷久久| 久久大香免费| 99热精品99| 综合超碰熟| 在线中文亚洲| 天堂婷婷五月在线| 五月天激情小说婷婷基地| 深爱激情网五月| 五月丁香六月婷婷中合网| 丁香五月综合高清在线| 精品国产va久久久久| 六月丁香视频网站| WWW,五月| 天天天干夜夜夜操| 日本欧美成人片AAAA| 国产婷婷综合| 国产精品久久久爽爽爽麻豆色哟哟| 91九色首页| 思思re最新视频| AV中文字幕夜夜操b天天摸bb| 婷婷桃色网| 久操97| 天天肏屄夜夜爽| 丁香色五月婷婷| www.精品99| 五月天激情网图片| av操一操| 丁香五月婷婷激情蜜桃| 久久这里都是精品免费| 婷婷五月色丁香在线看| 激情五月天 婷婷| 成人在线日韩欧美| 欧美另类五月激情| 亚洲操逼网| 九九久久99精品免费观看www| 国产做A爰片毛片A片美国| 97婷婷五月| 天堂久久精品| 久久婷婷视频| 五月伊人网| 国产精产国品一二三在观看| 婷婷五月天六点丁香五月| 99re这里只有精品国产99| 婷婷情色激情| 成人做爰黄A片免费看直播室男男| 色婷婷四虎| 婷婷深爱五月丁香网| 51国精产品自偷自偷综合| 殴美97色| 狠狠草在线观看| 五月婷婷,六月婷婷| 九九AV| 97av在线视频| 婷婷色五月色妇| 这里只有精品免费| 久久九九99| 伊人婷婷综合| 五月天激情站| 国产无遮挡又黄又爽免费网站| 超碰99热| 欧美操人| 日韩无码色色| 亚洲综合在线视频| 日本久久99| 五月天色婷婷激情综合| 婷婷五月激情综合啪啪| 五月激情视频| 婷婷伊人激情婷婷| 五月婷婷色欲| 久热9| 亚洲色欲AAAAAA| 播丁香五月婷婷欧美| 69午夜成人影片| 五月丁香 狠狠爱| 激情五月婷婷色| 婷婷玖玖丁香| 亚洲成av人影院| 人妻久久久久久久久妻久久久久| 五月丁香婷婷婷激情爱爱| 天天干天天干天天| 五月婷婷激情综合拍| 色综合香蕉| 97av在线视频| 日本在线观看aaa 99| 日日操日日爽| 深爱激情小说五月婷婷| 玖玖在线视| 91色性感五月婷婷丁香| 99re免费精品视频| 麻豆精品| 久久久一级AAA| 热久久99热欧美国产亚洲| 六月婷婷七月丁香| 伊人色综合影院视频| 国产亚洲99久久精品| www五月天com| 久久A热| 99天堂网| 丁香九月久久| 九九re精品视频在线观看| 性av| 99热伊人综合| 91干网站| 99色在线观看视频者| www.五月.com| 99久久99久久综合| 日日日日日| 九九色逼| 天天揷综合网| 国产又色又爽又黄又免费| 996热| 日韩人妻无码专区| 日韩成人网址| 亚洲激情五月天| 啊V视频在线观看| 在线播放中文字幕| 另类小说五月天| 日日天天干| 九九色99| 五月婷婷激情综合在线| 青青草搞屄视频网站| 99精品在线播放| 中文资源在线a | 婷婷五月天,影院| 日本综合久久| 桃色伊人在线| 亚洲视色| 操操啪| 婷婷午夜| 久9热插入| 九月婷婷综合网| 色色色97| 五月丁香999| 久久精彩视频99| 色婷婷五月网| 久久久网站| 国产精品99久久久久久久女警| 99在线精品免费视频| 色九九一二| 狠狠久久婷五月| 色亚洲色宗合| 天天操婷婷| 精品热九九| 激情綜合網址| 五月天婷婷色播| 五月天久久综合婷婷| 人人摸人人搞| 色五月婷婷青娱乐| 色色婷婷综合网| 91久久精品无码一区二区三区| 亚洲久热| 亚洲色久| 国产熟女一区二区三区五月婷| 国产小精品| 欧洲永久精品| 五月天激情视频| 乱精品一区字幕二区| 97碰碰视频| 久久aaaa片一区二区| 99九九在线观看免费| 激情骚五月| 激情婷婷综合| 色色色com| 婷婷伊人网| 婷婷婷婷婷开心无码播放| 久久久99精品免费观看| www色婷婷久久综合久色| 国产美女视频久| 久久sp免费视频| 天天爽天天摸天天爱| 天天综合精品| 五月天小说激情| 精品久久久91久久影视网| 思思热这里只有精品视频666| 亚洲第一综合| 九九人妻福利| 91在线就要啪| 五月丁香777| 丁香九月色| 五月开心深深爱激情综合| 少妇被躁爽到高潮无码文| 欧美久草在线日本一级特黄大片做受9在线观看韩国电影《两个女人》未删减-毛片 | 成人无码精品1区2区3区免费看| av婷婷丁香 六月| 北条麻妃九九九国产精品视频| 五月天婷婷在线观看精品男人| 日本不卡高字幕在线2019| 涩涩五| 亲子乱av一区二区三区的| 色五月天成人| 色六月丁香婷婷狠狠干| 日日操无码| 五月天婷婷乱论小说| 久久免费9| 亚洲中文字幕在线观看| 99国产视频网| 天天色情站| 久久33视频| 综合色激情| 99色视频在线观看最新| 丁香情色五月| www久久艹| 免費亭亭成人| 91九色无码日韩| 日碰日| 一区视频网站| 大香蕉AV电影在线| 97五月久久丁香婷婷| 日本精品。999| 九热...av| 日本少妇裸体做爰高潮片| 天天日综合| 五月丁香狠狠爱婷婷综合| 日韩在线视频中文字幕| 丁香五月天天久久综合小说| 狠狠色噜噜狠狠狠狠综合| 天天日天天爱天天噪| 色婷婷手机在线| 国产永久一黄| 色色婷婷综合| 99re欧美精品| 成人无码精品1区2区3区免费看| 99色色视频| 成人综合伍月天| 日韩狠狠色婷婷| 日本三久久| 久久久精品AV| 六月丁香综合| 久久色亭亭五月天| 色综合五月| 丁香美女五月天婷婷| 久久金品黃色| 欧美色99| 99A片| 综合视频久久| 91色久| 欧美搡BBBBB摔BBBBB| 色色欧美色色色| 国产看真人毛片爱做A片| 丁香六月婷婷一区| 狠狠色狠狠鲁| 97色色色色色| 丁香九月婷| 日本三级韩三级99久久| 日日干夜夜干| 91干| 婷婷丁香五月,狠狠综合| 伊人五月天在线| 久久9久| wwwss在线观看| 玖玖热视频| 99在线精品免费视频| 激情国产五月| 日韩在线99| 亚洲激情综合| 色婷丁香| 开心婷婷五月中文字幕组| 婷婷激情六月视频| 免费无码毛片一区二区A片| 久久五月婷婷综合网| 久碰婷婷视频| 伊人五月成人| 色噜噜狠狠色综无码久久合欧美| 99欧美精品99日本精品| 婷婷色在线| 五月天激情小说欧美激情| 久久国产色| 综合色七七| 五月婷免费视频久久久| 丁香婷婷色五月激情综合| 色呦精品| 婷婷丁香五另类网站| AV在线观看网站| 欧美超碰人人| 99热精品在线播放| 五月激情天| 一级性感黄色内射视频| 国产97色在线| 亚洲操逼网| 日日撸夜夜操| 亚洲第二AV| 另类图片婷婷五月天| 色墦五月丁香| 婷婷五月天影视网址| 丁香五月天堂| 五月丁香久久综合| 强壮的公次次弄得我高潮A片日本 | 99在线视频精品| 五月丁香自拍| 九九精品综合| 欧美影院婷婷| 99久久99视频只有精品| 久久AAAA片一区二区| 色八月婷婷| 国外亚洲成AV人片在线观看| 五月天艹天天| 五月天停停基地| 九九丁香社区欧美激情| 色狠久| 91久久五月天| 五月天激情小说| 婷婷热婷婷色| 14色综合婷婷| 久久这里只有精品热在99| 影音先锋女人av鲁色资源网小说免费| 色婷婷电影网| 99热无码| 色欲人妻综合aaaaaaaa网| 热久久这里只有精品| 好好干av| 色婷婷免费视频| 99热久久这里只有精品| 丁香五月婷婷影院| 色亚洲无码| 国产精品色婷婷AV综合色色| 丁香五月激情啪| 五月丁香影院| 99操免费视频| 99黄色| 久久久久8888| 午夜av网| 国产AV一区二区三区日韩| 91互操| 婷婷综合在线| 96精品久久久久久久久| 我爱va亚洲va52| 五月丁香精品| 九九热re99re6在线精品| 超碰在线91| www.婷婷五月| 五月综合无码| 丁香婷婷视频一区二区| 色网站99| 思思热久久阴99| 最新AV在线观看| 男男野外做爰全过程69| 色色婷| 亚洲精品国产成人AV在线| 五月丁香六月婷婷手机无线| 久久亚洲网| 99成人网一区| www久久久| 激情亚洲婷婷| 任我鲁这里有精品视频| 97色操| 丁香五月123| 在线观看av网站| 亚洲综合草草| 久草大| 99热都是精品| 色婷婷五月天激情久久| 丁香五月深爱五月婷婷| 免费精品66| 熟女婷婷网站一婷婷五月一丁香婷婷一婷婷激情网 | 夜夜夜夜操| 五月天婷婷色小说| 婷婷五月丁香综合人妻| 五月亭亭六月天| 少妇综合网| 成人精品人妻| 日本片日本片祼观看网站在线看中文版网页在线看 | 91热视频| eeuss人妻| 大香蕉人人人| 亚洲精品网站色视频| 广东99色在线| 婷婷性爱影院| 91伦| 五月丁花六月丁香综合| 色五月天综合网| 99久操视频| 天天爽在线视频| 婷婷五月天激情在线| 婷婷激情综合网| 农村熟妇高潮精品A片| 久热婷婷在线视频| 五月天欧美激情| 久久综合五月| 欧美日韩日韩成人| 色婷丨日丨天丨综合久久| 综合久久高清| 丁香婷婷综合影院| 九九热视频首页/这里只有精品| 开心婷婷五月| 婷婷久久五月天中文字幕在线观看| 婷婷六月婷婷| 色婷婷丁香五月| 91精品无码| www.henhengan| www婷婷色| WWW.五月天9999| 99这里只有精| av久热| 黄色成人网站在线播放| 草草影院爱爱| 人人摸人人澡人人| 精品导航在线x不卡| 午夜性爱影视一区77| 亚洲久热| 五月色婷婷影视在线电影| 91操碰| 99热国产国产| 日本黄色三级片内射| 色五月婷婷大| www,setingting| 五月激情天天干| 欧洲区自拍| 五月天综合在线观看| 91大神在线免费看视频全集男男一起操| 噜噜噜精品欧美成人在线观看| www.婷婷五月天,com| 激情五月天伊人影院| 婷婷WWW久久| 天天色天天操天天射| 五月丁香婷婷综合视频| 超碰在线人妻| 秋霞网在线观看理论91| 综合五月激情| 婷婷五月色色| 另类图片激情五月天| 色色色五月天婷婷| 色五月亚洲| 四月婷婷五月色综合| 国产特级毛片AAAAAAA高清| 丁香欧美| 五月婷婷六月丁香玖玖玫瑰91| 狠狠高潮精品亚洲1| 久久99久久99精品免视看婷| 色五月激情五月| 99视频网| 激情99。| 欧美婷婷九月| 97人人干| 丁香激情四射| 思思w99| 日本免费91| 成人国产欧美大片一区| 成人色图情色成人网 www.5b5b5bcom 五月天| 99亚洲精品视频| 天堂成人A片永久免费网站| 伊人啪啪网| 五月丁香六月日逼| 在线99精品| 婷婷99视频在线| 五月婷婷婷婷| 五月天丁香综合| 色五开心五月五月深深爱| 大功率国产在线| 狠狠色综合久久久久| 99热这里只有精品免费| 激情综合五月婷婷六月丁香| 婷婷爱综合| 天天久久人人| av在线中文| 色五月,婷婷大香蕉| 综合网精品99| 五月婷婷很很色| 色五月av| 亚洲综合激情五月久久| 九九久久玖玖爱| 综合色色五月| 久久aaaaa| 婷婷九月丁香| 五月婷婷co.m| 激情五月久久| 终合激情网| 九九热这里只有精品一| 丁香五月激情站| 色五月成人网| 五月色俺婷婷| 五月天婷婷色综合| 玖玖资源站中文| 九热视频| ww久久| 五月婷婷啪| 99热18| 亚洲精品久久久久久久久久飞鱼| 久久丁香五月天| 男女啪啪做爰高潮无遮挡| 国产婷婷色综合AV蜜臀AV| 色婷婷五月天| 碰99在线| 日本久久精品18| 国产人妻操逼| 大狠狠在线| 99视频这里有精品免费观看| 99无码黄色视频| 中文字幕在线日亚洲9| 超碰在线91| 激情综合网激情五月婷婷| 精品久9| 天天噜日日噜综合无码| 97色色-99久久| 婷婷色5月激情网| 亚洲av成人在线| 亚洲V国产V欧美V久久久久久| 激情久久伊人| 哇嘎成人久久| 九九九九九无码| 99亚州综合精品成人网| 五月天另类激情在线| 色综啪啪啪啪啪啪| 天天狠狠插| 9热精品| 江苏少妇性BBB搡BBB爽爽爽 | 色婷婷网大全在线| 色色五月婷| 久久这里有精品视频| 99色性爰网络| 秋霞日本免费毛片A片| 天天操夜夜玩!| 婷色五月天| 99视频日韩| 丁香婷婷综合五月天| 最新va在线播放| 成人中文网| 秋霞三级影视资源| 久久久中文| 五月婷婷亚洲色图| 天天爽天天摸| 亚洲国产无线乱码在线观看| 99热在线爱| 亚洲综合网激情小说| 九九re精品视频在线观看 | 综合五月草| 国产avapp 网| www久久久久久| 色天天综合成人网| 亚洲中文字幕在线观看| 国产亚洲在线观看| 色婷婷av在线观看| 色激情综合| 丝袜激情网| 婷婷色中文| www.狠狠操| 久啪欧美| 丁香婷婷五月天激情四射| 日本天堂爱爱| 色综合久久88色综合天天99| 久久久久久久久久久jjjj| 欧洲亚洲欧洲99久久| 日日操夜夜擼| 婷婷娱乐丁香综合网| 久久婷鲁| 狼友视频在线观看18| 亚洲综合婷婷| AV大香蕉| 久99久热只有精品国产99| 国产精产国品一二三在观看| 九九视频这里只有精彩| 激情九色| 婷婷开心激情| 开心五月综合激情综合五月| Caoub青青超碰 | 丁香五月影院| 成人在线观看国产| www,26uuu,c0m,色情| 一起草aV| 99精品综合视频| 天天成人丁香美女AV| 伊人三级激情| 99亚洲精品视频| 久久久五月激| 99热99思午夜精品| 天天爽天天操| 色99热| 五月天久久婷婷| 婷婷久久五月天| 天天激情站| 六月丁香成人| 91 原创 在线 九色| 日韩限制级大尺度黑料泄密大尺度视频一区二区在线观看 | 99视频一区| www,久久久| 182.t午在线观看| 超碰成人免费| 婷婷十月激情综合网| 五月婷婷六月丁香| av激情在线| 青青草免费公开视频| 99在线精品视频| 台湾综合丁香五月蜜桃| 色综合中文色综合网| 国产黄色在线| 九九成人视频| 99re8这里只有精品99re8热视频| 亚洲国产va| 色五月天综合| 五月丁香va| 欧美激情综合五月色丁香| 亚州成人综合在线| 午夜少妇在线观看视频| 丁香五月自拍| 婷婷丁香五月综合| 9色在线| 亚洲综合激情五月久久| 99热这里是精品| 欧美丰满熟妇BBB久久久| www.久久久久| 中文字幕无码人妻少妇免费视频| www超碰| 国产真实乱了老女人视频 | 日本乱论99| 婷婷久久性爱| 婷婷综合网站| 色婷婷最爱五月| 亚洲成人乱码av网站| 丁香五月天综合网| 色五月播五月| 亚洲欧洲另类| 99riav 亚洲| 丁香九色不卡aaa| 六月婷欧美| 激情六月下句是什么| 成人婷婷深爱综合网| 五月激情六月婷婷| 婷婷的99视频网站| 中文字幕无码人妻少妇免费视频| 九九色婷| 久久停停超碰| 婷婷综合五月色播| 五月天婷婷网站888| 性爱久久| 丁香五月天激情四射网| 日日干日日色| 日本va欧美va国产激情| 夜夜撸日日操| 色欲色香综合网站| 激情五月第四色| 色婷婷成人五月| 精品色色| 久久免费丁香| 五月熟妇婷婷久久| 激情五月天啪啪| 国精产品一区一区三区免费视频| 久久婷婷激情四射五月天| 天天天久久久| 激情五月天小说|五月天开心激情网|亚洲精品国产自在现线|黄色五月天 | 婷婷色五月91啪啪| 五月婷婷丁香| 五月婷婷丁香俺日污视频| 亚洲丁香花色| 性视频久久| 日日爱699| 亚洲视频一区| 五月丁香综合| 色婷婷综合久久久久| 一区二区你懂的| 午夜不卡成人一区二区| 婷婷五月天网| www.久久久.com| 日日夜夜天天| 亚洲蜜乳AV| 婷婷丁香在线播放| 久久se 综合网| 99久久国产宗和精品1上映| 91碰操| 六月激情婷婷综合| 久婷五月| 婷婷五月六月| 精品亚洲国产成AV人片传媒| 亚洲人人艹| 激情小说五月天中文字幕| 91操网| 黄色热99| 五月婷婷深深爱爱| 成人视频在线免费播放| 五月丁香亭亭A片| 激情综合网丁香| 婷婷色丁香五月| 丁香五月之久操视频| 九九久久精品| www.99日本| 五月天婷婷激情六月久久| 婷婷伊人綜合中文字幕| 综合99久久天天综合| 五月天婷亚洲综合在线嫩草网| 九九久久99| 婷婷五月天六点丁香五月| 婷婷亚洲欧美丁香五月| 亚洲另类电影| 五月丁香婷婷综合视频| 精品99视频| 久久 中文 日本| 狼人婷婷综合| 激情综合在线观看| 99热在线观看精品| www色五月| 台湾无码A片一区二区| www.婷婷,com| 五月玖玖| 丁香六月激| 激情五月综合亚洲另类| 美女天天艹人人爽| 成人综合网站| 99这里只有精品在线| 日本欧美成人片AAAA| 色亚洲色宗合| 丁香婷婷五月综合欧美另类| 婷婷丁香五月综合| 免费国产视频| 91操操| 丁香女人五月天| 极品人妻VIDEOSSS人妻| 五月花免费视频| 97碰碰视频| 九九碰九九爱97超碰| 黄网免费观看| 国产精品人人做人人爽人人添| 夜夜撸日日骑| 伊人玖玖精品| 99热官网| 《蜘蛛女》梁铮1995| 色婷婷激情| 91夫妻视频| 99热资源在线| 亚洲五月丁香综合网| 色吧综合网| 九九精品在线观看视频6| 亚洲五月天综合色| 婷婷色色综合| 久久九九爽| 99热欲| 日韩色五月| 丁香五月婷综合网| 久热精品视频在线观| www.婷婷久久五月天| 激情丁香九九五月综合网| 丁香五月成人论坛| 五月天综合在线| 五月婷婷六月激情| 丁香九月久久| 人人噜天天上| 五月丁香综合啪啪啪啪啪| 五月婷婷丁香啪啪| 五月综合激情网| 日日干天天| 婷婷五月天亚洲| 色婷婷五月基地在线| 9久久精品| 加勒比日本一区二区三区| 青青久在线视频免费观看| 在线播放成人网站| 五月婷婷激情日本| 综合网啪| 丁香五月综合| 噜噜吧天天爱| 任你操精品免费| 九九热99热| 欧美人妻一区二区| 久久久久久久合一狠狠做深爱| 袁子仪视频观看| 丁香五月aV| 丁香五月成人论坛| 99视频这里只有免费精品| 五月天婷婷基地丁香| 国产激情综合| 久久激情综合| 婷婷五月天日逼| 婷婷五月天激情在线观看| 日本激情ⅩXX免费视频| 色情·com| 久久A热| 五月天婷婷综合免费| 26uuu精品国产| 激情綜合W W W,激情五月天| 久久五月天综合| 99网99热| 日韩1区2区| 婷婷久草| 九九无毛| 久久精品91视频| 日韩影院三级| 99在线精品免费视频| 99热 日韩| 久久9热综合| 久久99精品久久久久久青青AR| www.zbzhongsen.com| 久久五月综合| 午夜激情四射影院| 婷婷五月天AV| 五月丁香婷婷人体| 丁香婷婷情色五月天| 99这里只有| 婷婷婷婷婷婷婷婷婷婷丁香| 九九九午夜视频| 婷婷的99视频网站| 五月丁香六月婷婷亚洲激情综合| 99热精品在线免费观看| 综合啪啪| 婷婷99狠| 婷婷九月激情网| 久青草影院| 情欲禁地| 99日本精品视频热| 狠狠色婷婷六月激情网| 性爱综合网| 一级无码作爱片| 色色色色欧洲| 玖玖资源在线视频| 欧美精品XXXXBBBB| 久久婷婷人人| 日韩综合大黄| 六月丁香婷| 久久免费操| 婷婷五月天伊人网| 九月丁香很很色| 天天搞夜夜叫| 五月天堂色| 色播播婷婷| www,99热| 91久久九| 亚洲亚洲人成综合网络| 五月丁香六月激情综合| 婷婷五月天堂| 天堂久久大香蕉| 五月天最新网| 密臀av无码人妻精品| 欧美va亚洲va在线播放| 久久综合99| 天天综合亚洲综合网天天αⅴ| 色99色| 日本久久性| 97热这里精品在线视频| 伊人久热91| 天天肏高清在线| 超碰com| 久久婷婷五月天激情| 光棍影院日韩精品| 色五月人妻| 丁香九月激情| 激情五月天视频| 白天AV月月| 午夜无码熟熟妇丰满人妻| 国产成人va在线| 丁香五月婷婷影院| 五月婷婷丁香五月 | 日韩AV免费电影在线播放| 天天干天天玩天天夜天天射天天操天天日蜜臀少妇 | 色婷婷综合在线| 99精品福利视频| 久久影视婷婷五月| 欧美Va婷色| 色欲九区| 五月天婷婷综合| 丁香婷婷久久综合在线| 色色色色色色五月婷婷| 玖玖爱综合网| 99国产小视频免费观看| 大地资源色婷婷视频在线| 草做免费在线观看| 天堂久久婷婷| 亚洲欧洲中文日韩久久AV乱码| 涩涩涩.com| 日韩欧美一级大黄网站| 风流少妇A片一区二区蜜桃 | 蜜臀av在线成人电影| 婷婷久久图片| 91狠狠综合久久久| 五月婷婷之综合激情| 五月婷婷在线视频免费观看| 丁香9月婷婷| 婷婷久久五月天| 九九色综合九九色| 五月丁香激情片| 97碰在线免费观看| 香蕉久久国产AV一区二区| 天天色天天日| 森林影视大全,最好看的2019年视频 | 五月婷婷草| 99燥99日| 综合色五月| 婷婷五月天高清无码| 色宗合,宗合网| 91精品久久久久久久| 激情五月天福利| caop视频| 久久久婷| 天堂久久精品| 久久久无码精品成人A片小说 | 丁香伊人网| 九九热视| 五月丁香六月婷婷亚洲| 色爱综合五月| 99热在线观看这里只有精品| 五月婷婷六月丁香| jiujiujiuwuyuetian| 国产婷婷五月| 97成人在线视频| 性色做爰片在线观看WW| 婷婷亚洲天堂| 99无码视频| 日本色婷婷| 人人草人人舔| 一起草av| 开心五月激情网| 免费观看的av| 91打屁股免费看| 国产亚洲精品久久久久久牛牛| 五月天久久婷婷| 天天色天天操天天射| 色综合久久天天综合网| 久久性操| 伊人在线视频| 北京熟妇搡BBBB搡BBBB| 丁香六月激情| http:色情日本com| 天天色2017| 婷婷五月综合色中文字幕| 婷婷玖玖丁香| 丁香五月婷婷激情网| 欧美在线视频99| 伊人久久激情图区五月| er99免费视频在线| 五月婷婷色五月| 人妻熟妇国产精品| 成人片黄网站色大片免费毛片| 日韩二区搞逼插逼毛片| 五月久久网| 婷婷中文无码| 337p午夜影院| 久99久99精品免| 亚洲色婷婷| 碰碰碰碰碰99| 丁香色婷婷| 婷婷丁香色五月久久88| 夜色综合网| 农村熟妇高潮精品A片| 五月丁香花激情啪啪网| 99久久综合网| 色五月天网| 丁香五月婷婷基地| 色在线免费观看| 另类五月婷婷| 五月天成人综合| 欧洲色区| 六月色激情| 激情久久天天| 天天色综网| 9久久久| 午夜爱爱爱成人| 久久婷婷综| 色综合中文综合网| wWw色五月| 亚洲操逼片| 91熟妇大香蕉| 日韩av干| 综合网色| 超碰人人干| 99在线精品视频| 久久综合站| 久久婷婷五月国产色综合激情| 天天干 夜夜爽| 丁香五月激情啪啪综合| 99久久国产成人精品| 久久婷婷五月丁香网| 婷婷五月综合免费在线| 人人干AV| 欧美性猛交AAAA片黑人 | 婷婷丁香亚洲色综合91| 深爱婷婷丁香五月激情| 久777| 色婷婷色人人射| 亚洲狠狠丁香婷婷香蕉| 婷婷丁香五另类网站| 六月婷婷五月丁香| 538久久| 三十熟女| 天天摸天天高潮天天爽| 1级欧美日韩| 婷婷色情六月| 夫妻超碰在线| 天天色天天操天天射| 色在线99| 日韩人妻在线观看| 日日干天天射| 日日操夜夜撸| 婷婷五月天色网久| 色婷婷91激情小说| 日本丁香五月| 51成人| 久久久久人妻| 亚洲小视频| 久久看婷婷| 天天插天天插| SESE无码AV| 97极品在线| 五月天婷婷综合| 五月天色婷婷基地| 色婷婷玖玖影院| 色婷婷av在线观看| 丁香五月天激情小说| 久久婷婷五月综合色和| 日日夜夜天天| 五月综合婷婷开心网| 超碰成人在线免费观看| 婷婷丁香九月| 五月天 综合 在线| 丁香六月综合激| 五月丁香激情综合网| 婷婷五月天第三页| 色五月成人婷婷| 国产精品成人网站| 丁香激情五月| 天天搞天天色综合| 怡红院院久久| 中文精品在| 久草 tingting| 九九AV| 丁香五月手机在线| 婷婷五月天成人综合网| 色婷婷香蕉| 婷婷色偷拍| 日本色啪| 久久小说| 思思热在线观看| 婷婷五月色激情欧美激情| 思思热久久久久思思热| 亚洲午夜精品久久久久久人妖| 在线sebiav精品视频| 国产精品国产成人国产三级| 五月婷婷久久综合| 大香蕉欧美在线| 日日夜夜久| 婷婷五月丁香久久| 狠狠 婷婷| 日韩草草草草草草草草草草草草| www98日本小时间到了| 丁香激情五月少妇| 91人人看| 99爱在线| 日本韩国视频在线观看社区免费的9| 狠狠干狠狠干| 亚洲热综合| 99亚洲天堂| 九月丁香婷婷| 99色在线| 亚洲mm色|