日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

CoreCLR源码探索(三) GC内存分配器的内部实现

發(fā)布時(shí)間:2023/12/4 编程问答 45 豆豆
生活随笔 收集整理的這篇文章主要介紹了 CoreCLR源码探索(三) GC内存分配器的内部实现 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

在前一篇中我講解了new是怎么工作的, 但是卻一筆跳過了內(nèi)存分配相關(guān)的部分.
在這一篇中我將詳細(xì)講解GC內(nèi)存分配器的內(nèi)部實(shí)現(xiàn).
在看這一篇之前請必須先看完微軟BOTR文檔中的"Garbage Collection Design",
原文地址是: https://github.com/dotnet/coreclr/blob/master/Documentation/botr/garbage-collection.md
譯文可以看知平軟件的譯文或我后來的譯文
請務(wù)必先看完"Garbage Collection Design", 否則以下內(nèi)容你很可能會無法理解

服務(wù)器GC和工作站GC

關(guān)于服務(wù)器GC和工作站GC的區(qū)別, 網(wǎng)上已經(jīng)有很多資料講解這篇就不再說明了.
我們來看服務(wù)器GC和工作站GC的代碼是怎么區(qū)別開來的.
默認(rèn)編譯CoreCLR會對同一份代碼以使用服務(wù)器GC還是工作站GC的區(qū)別編譯兩次, 分別在SVR和WKS命名空間中:

源代碼: https://github.com/dotnet/coreclr/blob/release/1.1.0/src/gc/gcsvr.cpp

#define SERVER_GC 1namespace SVR { #include "gcimpl.h"#include "gc.cpp"}

源代碼: https://github.com/dotnet/coreclr/blob/release/1.1.0/src/gc/gcwks.cpp

#ifdef SERVER_GC#undef SERVER_GC#endifnamespace WKS { #include "gcimpl.h"#include "gc.cpp"}

當(dāng)定義了SERVER_GC時(shí), MULTIPLE_HEAPS和會被同時(shí)定義.
定義了MULTIPLE_HEAPS會使用多個(gè)堆(Heap), 服務(wù)器GC每個(gè)cpu核心都會對應(yīng)一個(gè)堆(默認(rèn)), 工作站GC則全局使用同一個(gè)堆.

源代碼: https://github.com/dotnet/coreclr/blob/release/1.1.0/src/gc/gcimpl.h

#ifdef SERVER_GC#define MULTIPLE_HEAPS 1#endif // SERVER_GC

后臺GC無論是服務(wù)器GC還是工作站GC都會默認(rèn)支持, 但運(yùn)行時(shí)不一定會啟用.

源代碼: https://github.com/dotnet/coreclr/blob/release/1.1.0/src/gc/gcpriv.h

#define BACKGROUND_GC //concurrent background GC (requires WRITE_WATCH)

我們從https://www.microsoft.com/net下回來的CoreCLR安裝包中已經(jīng)包含了服務(wù)器GC和后臺GC的支持,但默認(rèn)不會開啟.
開啟它們可以修改project.json中的·runtimeOptions·節(jié), 例子如下:

{"runtimeOptions": {"configProperties": {"System.GC.Server": true,"System.GC.Concurrent": true}}}

設(shè)置后發(fā)布項(xiàng)目可以看到coreapp.runtimeconfig.json, 運(yùn)行時(shí)會只看這個(gè)文件.
微軟官方的文檔: https://docs.microsoft.com/en-us/dotnet/articles/core/tools/project-json

GC相關(guān)的類和它們的關(guān)系

我先用兩張圖來解釋服務(wù)器GC和工作站GC下GC相關(guān)的類的關(guān)系

圖中一共有5個(gè)類型

  • GCHeap

    • 實(shí)現(xiàn)了IGCHeap接口, 公開GC層的接口給EE(運(yùn)行引擎)層調(diào)用

    • 在工作站GC下只有一個(gè)實(shí)例, 不會關(guān)聯(lián)gc_heap對象, 因?yàn)楣ぷ髡綠C下gc_heap的所有成員都會被定義為靜態(tài)變量

    • 在服務(wù)器GC下有1+cpu核心數(shù)個(gè)實(shí)例(默認(rèn)), 第一個(gè)實(shí)例用于當(dāng)接口, 其它對應(yīng)cpu核心的實(shí)例都會各關(guān)聯(lián)一個(gè)gc_heap實(shí)例

  • gc_heap

    • 內(nèi)部的使用的堆類型, 用于負(fù)責(zé)內(nèi)存的分配和回收

    • 在工作站GC下無實(shí)例, 所有成員都會定義為靜態(tài)變量

    • 在工作站GC下generation_table這個(gè)成員不會被定義, 而是使用全局變量generation_table

    • 在服務(wù)器GC下有cpu核心數(shù)個(gè)實(shí)例(默認(rèn)), 各關(guān)聯(lián)一個(gè)GCHeap實(shí)例

  • generation

    • 儲存各個(gè)代的信息, 例如地址范圍和使用的段

    • 儲存在generation_table中, 一個(gè)generation_table包含了5個(gè)generation, 前面的是0 1 2 3代, 最后一個(gè)不會被初始化和使用

    • 在工作站GC下只有1個(gè)generation_table, 就是全局變量generation_table

    • 在服務(wù)器GC下generation_table是gc_heap的成員, 有多少個(gè)gc_heap就有多少個(gè)generation_table

  • heap_segment

    • 堆段, 供分配器使用的一段內(nèi)存, 用鏈表形式保存

    • 每個(gè)gc_heap中都有一個(gè)或一個(gè)以上的segment

    • 每個(gè)gc_heap中都有一個(gè)ephemeral heap segment(用于存放最年輕對象)

    • 每個(gè)gc_heap中都有一個(gè)large heap segment(用于存放大對象)

    • 在工作站GC下segment的默認(rèn)大小是256M(0x10000000字節(jié))

    • 在服務(wù)器GC下segment的默認(rèn)大小是4G(0x100000000字節(jié))

  • alloc_context

    • 分配上下文, 指向segment中的一個(gè)范圍, 用于實(shí)際分配對象

    • 每個(gè)線程都有自己的分配上下文, 因?yàn)橹赶虻姆秶灰粯铀灾灰?dāng)前范圍還有足夠空間, 分配對象時(shí)不需要線程鎖

    • 分配上下文的默認(rèn)范圍是8K, 也叫分配單位(Allocation Quantum)

    • 分配小對象時(shí)會從這8K中分配, 分配大對象時(shí)則會直接從段(segment)中分配

    • 代0(gen 0)還有一個(gè)默認(rèn)的分配上下文供內(nèi)部使用, 和線程無關(guān)

GCHeap的源代碼摘要:

GCHeap的定義: https://github.com/dotnet/coreclr/blob/release/1.1.0/src/gc/gcimpl.h#L61
全局的GCHeap實(shí)例: https://github.com/dotnet/coreclr/blob/release/1.1.0/src/gc/gc.h#L105

這里是1.1.0的代碼, 1.2.0全局GCHeap會分別保存到gcheaputilities.h(g_pGCHeap)和gc.cpp(g_theGCHeap), 兩處地方都指向同一個(gè)實(shí)例.

// 相當(dāng)于extern GCHeap* g_pGCHeap;GPTR_DECL(GCHeap, g_pGCHeap);

gc_heap的源代碼摘要:

gc_heap的定義: https://github.com/dotnet/coreclr/blob/release/1.1.0/src/gc/gcpriv.h#L1079
這個(gè)類有300多個(gè)成員(從ephemeral_low開始),

generation的源代碼摘要:

generation的定義: https://github.com/dotnet/coreclr/blob/release/1.1.0/src/gc/gcpriv.h#L754
這里我只列出這篇文章涉及到的成員

class generation {public: ? ?// 默認(rèn)的分配上下文alloc_context ? allocation_context; ? ?// 用于分配的最新的堆段heap_segment* ? allocation_segment; ? ?// 開始的堆段PTR_heap_segment start_segment; ? ?// 用于區(qū)分對象在哪個(gè)代的指針, 在此之后的對象都屬于這個(gè)代, 或比這個(gè)代更年輕的代uint8_t* ? ? ? ?allocation_start; ? ?// 用于儲存和分配自由對象(Free Object, 又名Unused Array, 可以理解為碎片空間)的分配器allocator ? ? ? free_list_allocator; ? ?// 這個(gè)代是第幾代int gen_num; };

heap_segment的源代碼摘要:

heap_segment的定義: https://github.com/dotnet/coreclr/blob/release/1.1.0/src/gc/gcpriv.h#L4166
這里我只列出這篇文章涉及到的成員

class heap_segment {public: ? ?// 已實(shí)際分配地址 (mem + 已分配大小)// 更新有可能會延遲uint8_t* ? ? ? ?allocated; ? ?// 已提交到物理內(nèi)存的地址 (this + SEGMENT_INITIAL_COMMIT)uint8_t* ? ? ? ?committed; ? ?// 預(yù)留到的分配地址 (this + size)uint8_t* ? ? ? ?reserved; ? ?// 已使用地址 (mem + 已分配大小 - 對象頭大小)uint8_t* ? ? ? ?used; ? ?// 初始分配地址 (服務(wù)器gc開啟時(shí): this + OS_PAGE_SIZE, 否則: this + sizeof(*this) + alignment)uint8_t* ? ? ? ?mem; ? ?// 下一個(gè)堆段PTR_heap_segment next; ? ?// 屬于的gc_heap實(shí)例gc_heap* ? ? ? ?heap; };

alloc_context的源代碼摘要:

alloc_context的定義: https://github.com/dotnet/coreclr/blob/release/1.1.0/src/gc/gc.h#L162
這里是1.1.0的代碼, 1.2.0這些成員移動(dòng)到了gcinterface.h的gc_alloc_context, 但是成員還是一樣的

struct alloc_context { ? ?// 下一次分配對象的開始地址uint8_t* ? ? ? alloc_ptr; ? ?// 可以分配到的最終地址uint8_t* ? ? ? alloc_limit; ? ?// 歷史分配的小對象大小合計(jì)int64_t ? ? ? ?alloc_bytes; //Number of bytes allocated on SOH by this context// 歷史分配的大對象大小合計(jì)int64_t ? ? ? ?alloc_bytes_loh; //Number of bytes allocated on LOH by this context#if defined(FEATURE_SVR_GC)// 空間不夠需要獲取更多空間時(shí)使用的GCHeap// 分alloc_heap和home_heap的作用是平衡各個(gè)heap的使用量,這樣并行回收時(shí)可以減少處理各個(gè)heap的時(shí)間差異SVR::GCHeap* ? alloc_heap; ? ?// 原來的GCHeapSVR::GCHeap* ? home_heap;#endif // defined(FEATURE_SVR_GC)// 歷史分配對象次數(shù)int ? ? ? ? ? ?alloc_count; };

堆段的物理結(jié)構(gòu)

為了更好理解下面即將講解的代碼,請先看這兩張圖片

分配對象內(nèi)存的代碼流程

還記得上篇我提到過的AllocateObject函數(shù)嗎? 這個(gè)函數(shù)由JIT_New調(diào)用, 負(fù)責(zé)分配一個(gè)普通的對象.
讓我們來繼續(xù)跟蹤這個(gè)函數(shù)的內(nèi)部吧:

AllocateObject函數(shù)的內(nèi)容: https://github.com/dotnet/coreclr/blob/release/1.1.0/src/vm/gchelpers.cpp#L931
AllocateObject的其他版本同樣也會調(diào)用AllocAlign8或Alloc函數(shù), 下面就不再貼出其他版本的函數(shù)代碼了.

Alloc函數(shù)的內(nèi)容: https://github.com/dotnet/coreclr/blob/release/1.1.0/src/vm/gchelpers.cpp#L931

GetGCHeap函數(shù)的內(nèi)容: https://github.com/dotnet/coreclr/blob/release/1.1.0/src/gc/gc.h#L377

static GCHeap *GetGCHeap(){LIMITED_METHOD_CONTRACT; ? ?// 返回全局的GCHeap實(shí)例// 注意這個(gè)實(shí)例只作為接口使用,不和具體的gc_heap實(shí)例關(guān)聯(lián)_ASSERTE(g_pGCHeap != NULL); ? ?return g_pGCHeap; }

GetThreadAllocContext函數(shù)的內(nèi)容: https://github.com/dotnet/coreclr/blob/release/1.1.0/src/vm/gchelpers.cpp#L54

inline alloc_context* GetThreadAllocContext(){WRAPPER_NO_CONTRACT;assert(GCHeap::UseAllocationContexts()); ?
?// 獲取當(dāng)前線程并返回m_alloc_context成員的地址return & GetThread()->m_alloc_context; }

GCHeap::Alloc函數(shù)的內(nèi)容: https://raw.githubusercontent.com/dotnet/coreclr/release/1.1.0/src/gc/gc.cpp

分配小對象內(nèi)存的代碼流程

讓我們來看一下小對象的內(nèi)存是如何分配的

allocate函數(shù)的內(nèi)容: https://raw.githubusercontent.com/dotnet/coreclr/release/1.1.0/src/gc/gc.cpp
這個(gè)函數(shù)嘗試從分配上下文分配內(nèi)存, 失敗時(shí)調(diào)用allocate_more_space為分配上下文指定新的空間
這里的前半部分的處理還有匯編版本, 可以看上一篇分析的JIT_TrialAllocSFastMP_InlineGetThread函數(shù)

allocate_more_space函數(shù)的內(nèi)容: https://raw.githubusercontent.com/dotnet/coreclr/release/1.1.0/src/gc/gc.cpp
這個(gè)函數(shù)會在有多個(gè)heap時(shí)調(diào)用balance_heaps平衡各個(gè)heap的使用量, 然后再調(diào)用try_allocate_more_space函數(shù)


try_allocate_more_space函數(shù)的內(nèi)容: https://raw.githubusercontent.com/dotnet/coreclr/release/1.1.0/src/gc/gc.cpp
這個(gè)函數(shù)會獲取MSL鎖, 檢查是否有必要觸發(fā)GC, 然后根據(jù)gen_number參數(shù)調(diào)用allocate_small或allocate_large函數(shù)

allocate_small函數(shù)的內(nèi)容: https://raw.githubusercontent.com/dotnet/coreclr/release/1.1.0/src/gc/gc.cpp
循環(huán)嘗試進(jìn)行各種回收內(nèi)存的處理和調(diào)用soh_try_fit函數(shù), soh_try_fit函數(shù)分配成功或手段已經(jīng)用盡時(shí)跳出循環(huán)


soh_try_fit函數(shù)的內(nèi)容: https://raw.githubusercontent.com/dotnet/coreclr/release/1.1.0/src/gc/gc.cpp
這個(gè)函數(shù)會先嘗試調(diào)用a_fit_free_list_p從自由對象列表中分配, 然后嘗試調(diào)用a_fit_segment_end_p從堆段結(jié)尾分配


a_fit_free_list_p函數(shù)的內(nèi)容: https://raw.githubusercontent.com/dotnet/coreclr/release/1.1.0/src/gc/gc.cpp
這個(gè)函數(shù)會嘗試從自由對象列表中找到足夠大小的空間, 如果找到則把分配上下文指向這個(gè)空間

a_fit_segment_end_p函數(shù)的內(nèi)容: https://raw.githubusercontent.com/dotnet/coreclr/release/1.1.0/src/gc/gc.cpp
這個(gè)函數(shù)會嘗試在堆段的結(jié)尾找到一塊足夠大小的空間, 如果找到則把分配上下文指向這個(gè)空間

adjust_limit_clr函數(shù)的內(nèi)容: https://raw.githubusercontent.com/dotnet/coreclr/release/1.1.0/src/gc/gc.cpp
這個(gè)函數(shù)會給分配上下文設(shè)置新的范圍
不管是從自由列表還是堆段的結(jié)尾分配都會調(diào)用這個(gè)函數(shù), 從自由列表分配時(shí)seg參數(shù)會是nullptr
調(diào)用完這個(gè)函數(shù)以后分配上下文就有足夠的空間了, 回到gc_heap::allocate的retry就可以成功的分配到對象的內(nèi)存

總結(jié)小對象內(nèi)存的代碼流程

  • allocate: 嘗試從分配上下文分配內(nèi)存, 失敗時(shí)調(diào)用allocate_more_space為分配上下文指定新的空間

    • try_allocate_more_space: 檢查是否有必要觸發(fā)GC, 然后根據(jù)gen_number參數(shù)調(diào)用allocate_small或allocate_large函數(shù)

    • soh_try_fit: 先嘗試調(diào)用a_fit_free_list_p從自由對象列表中分配, 然后嘗試調(diào)用a_fit_segment_end_p從堆段結(jié)尾分配

    • adjust_limit_clr: 給分配上下文設(shè)置新的范圍

    • adjust_limit_clr: 給分配上下文設(shè)置新的范圍

    • a_fit_free_list_p: 嘗試從自由對象列表中找到足夠大小的空間, 如果找到則把分配上下文指向這個(gè)空間

    • a_fit_segment_end_p: 嘗試在堆段的結(jié)尾找到一塊足夠大小的空間, 如果找到則把分配上下文指向這個(gè)空間

    • allocate_small: 循環(huán)嘗試進(jìn)行各種回收內(nèi)存的處理和調(diào)用soh_try_fit函數(shù)

    • allocate_more_space: 調(diào)用try_allocate_more_space函數(shù)

分配大對象內(nèi)存的代碼流程

讓我們來看一下大對象的內(nèi)存是如何分配的
分配小對象我們從gc_heap::allocate開始跟蹤, 這里我們從gc_heap::allocate_large_object開始跟蹤

allocate_large_object函數(shù)的內(nèi)容: https://raw.githubusercontent.com/dotnet/coreclr/release/1.1.0/src/gc/gc.cpp
這個(gè)函數(shù)和allocate函數(shù)不同的是它不會嘗試從分配上下文中分配, 而是直接從堆段中分配

allocate_more_space這個(gè)函數(shù)我們在之前已經(jīng)看過了, 忘掉的可以向前翻
這個(gè)函數(shù)會調(diào)用try_allocate_more_space函數(shù)
try_allocate_more_space函數(shù)在分配大對象時(shí)會調(diào)用allocate_large函數(shù)

allocate_large函數(shù)的內(nèi)容: https://raw.githubusercontent.com/dotnet/coreclr/release/1.1.0/src/gc/gc.cpp
這個(gè)函數(shù)的結(jié)構(gòu)和alloc_small相似但是內(nèi)部處理的細(xì)節(jié)不一樣

loh_try_fit函數(shù)的內(nèi)容: https://raw.githubusercontent.com/dotnet/coreclr/release/1.1.0/src/gc/gc.cpp
處理和soh_try_fit差不多, 先嘗試調(diào)用a_fit_free_list_large_p從自由對象列表中分配, 然后嘗試調(diào)用loh_a_fit_segment_end_p從堆段結(jié)尾分配


a_fit_free_list_large_p函數(shù)的內(nèi)容: https://raw.githubusercontent.com/dotnet/coreclr/release/1.1.0/src/gc/gc.cpp
和a_fit_free_list_p的處理基本相同, 但是在支持LOH壓縮時(shí)會生成填充對象, 并且有可能會調(diào)用bgc_loh_alloc_clr函數(shù)

adjust_limit_clr這個(gè)函數(shù)我們在看小對象的代碼流程時(shí)已經(jīng)看過
這里看bgc_loh_alloc_clr函數(shù)的內(nèi)容: https://raw.githubusercontent.com/dotnet/coreclr/release/1.1.0/src/gc/gc.cpp
這個(gè)函數(shù)是在后臺GC運(yùn)行時(shí)分配大對象使用的, 需要照顧到運(yùn)行中的后臺GC


loh_a_fit_segment_end_p函數(shù)的內(nèi)容: https://raw.githubusercontent.com/dotnet/coreclr/release/1.1.0/src/gc/gc.cpp
這個(gè)函數(shù)會遍歷第3代的堆段鏈表逐個(gè)調(diào)用a_fit_segment_end_p函數(shù)嘗試分配

總結(jié)大對象內(nèi)存的代碼流程

  • allocate_large_object: 調(diào)用allocate_more_space為一個(gè)空的分配上下文指定新的空間, 空間大小會等于對象的大小

    • try_allocate_more_space: 檢查是否有必要觸發(fā)GC, 然后根據(jù)gen_number參數(shù)調(diào)用allocate_small或allocate_large函數(shù)

    • loh_try_fit: 先嘗試調(diào)用a_fit_free_list_large_p從自由對象列表中分配, 然后嘗試調(diào)用loh_a_fit_segment_end_p從堆段結(jié)尾分配

    • a_fit_segment_end_p: 嘗試在堆段的結(jié)尾找到一塊足夠大小的空間, 如果找到則把分配上下文指向這個(gè)空間

    • bgc_loh_alloc_clr: 給分配上下文設(shè)置新的范圍, 照顧到后臺GC

    • adjust_limit_clr: 給分配上下文設(shè)置新的范圍

    • bgc_loh_alloc_clr: 給分配上下文設(shè)置新的范圍, 照顧到后臺GC

    • adjust_limit_clr: 給分配上下文設(shè)置新的范圍

    • a_fit_free_list_large_p: 嘗試從自由對象列表中找到足夠大小的空間, 如果找到則把分配上下文指向這個(gè)空間

    • loh_a_fit_segment_end_p: 遍歷第3代的堆段鏈表逐個(gè)調(diào)用a_fit_segment_end_p函數(shù)嘗試分配

    • allocate_large: 循環(huán)嘗試進(jìn)行各種回收內(nèi)存的處理和調(diào)用soh_try_fit函數(shù)

    • allocate_more_space: 調(diào)用try_allocate_more_space函數(shù)

CoreCLR如何管理系統(tǒng)內(nèi)存 (windows, linux)

看到這里我們應(yīng)該知道分配上下文, 小對象, 大對象的內(nèi)存都是來源于堆段, 那堆段的內(nèi)存來源于哪里呢?
GC在程序啟動(dòng)時(shí)會創(chuàng)建默認(rèn)的堆段, 調(diào)用流程是init_gc_heap => get_initial_segment => make_heap_segment
如果默認(rèn)的堆段不夠用會創(chuàng)建新的堆段
小對象的堆段會通過gc1 => plan_phase => soh_get_segment_to_expand => get_segment => make_heap_segment創(chuàng)建
大對象的堆段會通過allocate_large => loh_get_new_seg => get_large_segment => get_segment_for_loh => get_segment => make_heap_segment創(chuàng)建

默認(rèn)的堆段會通過next_initial_memory分配內(nèi)存, 這一塊內(nèi)存在程序啟動(dòng)時(shí)從reserve_initial_memory函數(shù)申請
reserve_initial_memory函數(shù)和make_heap_segment函數(shù)都會調(diào)用virtual_alloc函數(shù)

因?yàn)檎{(diào)用流程很長我這里就不一個(gè)個(gè)函數(shù)貼代碼了, 有興趣的可以自己去跟蹤
virtual_alloc函數(shù)的調(diào)用流程是

virtual_alloc => GCToOSInterface::VirtualReserve => ClrVirtualAllocAligned => ClrVirtualAlloc => CExecutionEngine::ClrVirtualAlloc => EEVirtualAlloc => VirtualAlloc

如果是windows, VirtualAlloc就是同名的windows api
如果是linux或者macosx, 調(diào)用流程是VirtualAlloc => VIRTUALReserveMemory => ReserveVirtualMemory
ReserveVirtualMemory函數(shù)會調(diào)用mmap函數(shù)

ReserveVirtualMemory函數(shù)的內(nèi)容: https://github.com/dotnet/coreclr/blob/release/1.1.0/src/pal/src/map/virtual.cpp#L894

CoreCLR在從系統(tǒng)申請內(nèi)存時(shí)會使用VirtualAlloc或mmap模擬的VirtualAlloc
申請后會得到一塊尚未完全提交到物理內(nèi)存的虛擬內(nèi)存(注意保護(hù)模式是PROT_NONE, 表示該塊內(nèi)存不能讀寫執(zhí)行, 內(nèi)核無需設(shè)置它的PageTable)
如果你有興趣可以看一下CoreCLR的虛擬內(nèi)存占用, 工作站GC啟動(dòng)時(shí)就占了1G多, 服務(wù)器GC啟動(dòng)時(shí)就占用了20G

之后CoreCLR會根據(jù)使用慢慢的把使用的部分提交到物理內(nèi)存, 流程是

GCToOSInterface::VirtualCommit => ClrVirtualAlloc => CExecutionEngine::ClrVirtualAlloc => EEVirtualAlloc => VirtualAlloc

如果是windows, VirtualAlloc是同名的windowsapi, 地址會被顯式指定且頁保護(hù)模式為可讀寫(PAGE_READWRITE)
如果是linux或者macosx, VirtualAlloc會調(diào)用VIRTUALCommitMemory, 且內(nèi)部會調(diào)用mprotect來設(shè)置該頁為可讀寫(PROT_READ|PROT_WRITE)

當(dāng)GC回收了垃圾對象, 不再需要部分內(nèi)存時(shí)會把內(nèi)存還給系統(tǒng), 例如回收小對象后的流程是

gc1 => decommit_ephemeral_segment_pages => decommit_heap_segment_pages => GCToOSInterface::VirtualDecommit

GCToOSInterface::VirtualDecommit的調(diào)用流程是

GCToOSInterface::VirtualDecommit => ClrVirtualFree => CExecutionEngine::ClrVirtualFree => EEVirtualFree => VirtualFree

如果是windows, VirtualFree是同名的windowsapi, 表示該部分虛擬內(nèi)存已經(jīng)不再使用內(nèi)核可以重置它們的PageTable
如果是linux或者macosx, VirtualFree通過mprotect模擬, 設(shè)置該頁的保護(hù)模式為PROT_NONE

VirtualFree函數(shù)的內(nèi)容: https://github.com/dotnet/coreclr/blob/release/1.1.0/src/pal/src/map/virtual.cpp#L1291

我們可以看出, CoreCLR管理系統(tǒng)內(nèi)存的方式比較底層
在windows上使用了VirtualAlloc和VirtualFree
在linux上使用了mmap和mprotect
而不是使用傳統(tǒng)的malloc和new
這樣會帶來更好的性能但同時(shí)增加了移植到其他平臺的成本

動(dòng)態(tài)調(diào)試GC分配對象內(nèi)存的過程

要深入學(xué)習(xí)CoreCLR光看代碼是很難做到的, 比如這次大部分來源的gc.cpp有接近37000行的代碼, 如果直接看可以把一個(gè)像我這樣的普通人看瘋
為了很好的了解CoreCLR的工作原理這次我自己編譯了CoreCLR并在本地用lldb進(jìn)行了調(diào)試, 這里我分享一下編譯和調(diào)試的過程
這里我使用了ubuntu 16.04 LTS, 因?yàn)閘inux上部署編譯環(huán)境比windows要簡單很多

下載CORECLR:

git clone https://github.com/dotnet/coreclr.git

切換到你正在使用的版本, 請務(wù)必切換不要直接去編譯master分支

git checkout v1.1.0

參考微軟的幫助安裝好需要的包

# https://github.com/dotnet/coreclr/blob/master/Documentation/building/linux-instructions.mdecho "deb http://llvm.org/apt/trusty/ llvm-toolchain-trusty-3.6 main" | sudo tee /etc/apt/sources.list.d/llvm.listwget -O - http://llvm.org/apt/llvm-snapshot.gpg.key | sudo apt-key add -sudo apt-get update sudo apt-get install cmake llvm-3.5 clang-3.5 lldb-3.6 lldb-3.6-dev libunwind8 libunwind8-dev gettext libicu-dev liblttng-ust-dev libcurl4-openssl-dev libssl-dev uuid-dev cd coreclr ./build.sh

執(zhí)行build.sh會從微軟的網(wǎng)站下載一些東西, 如果很長時(shí)間都下載不成功你應(yīng)該考慮掛點(diǎn)什么東西
編譯過程需要幾十分鐘, 完成以后可以在coreclr/bin/Product/Linux.x64.Debug下看到編譯結(jié)果

完成以后用dotnet創(chuàng)建一個(gè)新的可執(zhí)行項(xiàng)目, 在project.json中添加runtimes節(jié)

{"runtimes": {"ubuntu.16.04-x64": {}} }

Program.cs的代碼可以隨意寫, 想測哪部分就寫哪部分的代碼,我這里寫的是多線程分配內(nèi)存然后釋放的代碼

寫完以后編譯并發(fā)布

dotnet restoredotnet publish

發(fā)布后bin/Debug/netcoreapp1.1/ubuntu16.04-x64/publish會多出最終發(fā)布的文件
把剛才CoreCLR編譯出來的coreclr/bin/Product/Linux.x64.Debug下的所有文件復(fù)制到publish目錄下, 并覆蓋原有文件
微軟官方的調(diào)試文檔可見 https://github.com/dotnet/coreclr/blob/release/1.1.0/Documentation/building/debugging-instructions.md

使用lldb啟動(dòng)進(jìn)程, 這里我項(xiàng)目名稱是coreapp所以publish下的可執(zhí)行文件名稱也是coreapp

lldb-3.6 ./coreapp

啟動(dòng)進(jìn)程后可以打命令來調(diào)試, 需要中斷(暫停)程序運(yùn)行可以按下ctrl+c

這張圖中的命令

b allocate_small 給函數(shù)下斷點(diǎn), 這里的allocate_small雖然全名是SVR::gc_heap::allocate_small或WKS::
gc_heap::allocate_small 但是lldb允許用短名稱下斷點(diǎn), 碰到多個(gè)符合的函數(shù)會一并截取r 運(yùn)行程序, 之前在pending中的斷點(diǎn)如果在程序運(yùn)行后可以確定內(nèi)存位置則實(shí)際的添加斷點(diǎn)bt 查看當(dāng)前的堆棧調(diào)用樹, 可以看當(dāng)前被調(diào)用的函數(shù)的來源是哪些函數(shù)


這張圖中的命令

n 步過, 遇到函數(shù)不會進(jìn)去, 如果需要步進(jìn)可以用s 另外步過匯編和步進(jìn)匯編是ni和sifr v 查看當(dāng)前堆棧幀中的變量 也就是傳入的參數(shù)和本地變量p acontext->alloc_ptr p *acontext打印全局或本地變量的值, 這個(gè)命令是調(diào)試中必用的命令, 不僅支持查看變量還支持計(jì)算表達(dá)式


這張圖中的命令

c繼續(xù)中斷進(jìn)程直到退出或下一個(gè)斷點(diǎn)br del 刪除之前設(shè)置的所有斷點(diǎn)


這張圖顯示的是線程列表中的第一個(gè)線程的分配上下文內(nèi)容, 0x168可以通過p &((Thread*)nullptr)->m_Link計(jì)算得出(就是offsetof)
這張圖中的命令

me re -s4 -fx -c12 0x00007fff5c006f00讀取0x00007fff5c006f00開始的內(nèi)存, 單位是4byte, 表現(xiàn)形式是hex, 顯示12個(gè)單位


lldb不僅能調(diào)試CoreCLR自身的代碼
還能用來調(diào)試用戶寫的程序代碼, 需要微軟的SOS插件支持
詳細(xì)可以看微軟的官方文檔 https://github.com/dotnet/coreclr/blob/release/1.1.0/Documentation/building/debugging-instructions.md

最后附上在這次分析中我常用的lldb命令
學(xué)習(xí)lldb可以查看官方的Tutorial和GDB and LLDB command examples

參考鏈接

https://github.com/dotnet/coreclr/blob/master/Documentation/botr/garbage-collection.md
https://github.com/dotnet/coreclr/blob/release/1.1.0/src/gc/gcsvr.cpp
https://github.com/dotnet/coreclr/blob/release/1.1.0/src/gc/gcwks.cpp
https://github.com/dotnet/coreclr/blob/release/1.1.0/src/gc/gcimpl.h
https://github.com/dotnet/coreclr/blob/release/1.1.0/src/gc/gcpriv.h
https://github.com/dotnet/coreclr/blob/release/1.1.0/src/gc/gc.h#L162
https://github.com/dotnet/coreclr/blob/release/1.1.0/src/vm/gchelpers.cpp#L931
https://raw.githubusercontent.com/dotnet/coreclr/release/1.1.0/src/gc/gc.cpp
https://github.com/dotnet/coreclr/blob/release/1.1.0/src/pal/src/map/virtual.cpp#L894
https://github.com/dotnet/coreclr/blob/master/Documentation/building/linux-instructions.md
https://github.com/dotnet/coreclr/blob/release/1.1.0/Documentation/building/debugging-instructions.md
https://docs.microsoft.com/en-us/dotnet/articles/core/tools/project-json
https://github.com/dotnet/coreclr/issues/8959
https://github.com/dotnet/coreclr/issues/8995
https://github.com/dotnet/coreclr/issues/9053

因?yàn)間c的代碼實(shí)在龐大并且注釋少, 這次的分析我不僅在官方的github上提問了還動(dòng)用到lldb才能做到初步的理解
下一篇我將講解GC內(nèi)存回收器的內(nèi)部實(shí)現(xiàn), 可能需要的時(shí)間更長, 請耐心等待吧

原文地址:http://www.cnblogs.com/zkweb/p/6379080.html


.NET社區(qū)新聞,深度好文,微信中搜索dotNET跨平臺或掃描二維碼關(guān)注

總結(jié)

以上是生活随笔為你收集整理的CoreCLR源码探索(三) GC内存分配器的内部实现的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。

在线日韩视频 | 国产精品久久免费看 | 亚州视频在线 | 91精品在线免费观看视频 | 欧美日韩一区二区三区在线免费观看 | 日韩美女av在线 | 亚洲韩国一区二区三区 | 在线一级片| 五月婷婷黄色网 | 色婷婷国产精品一区在线观看 | 免费成人在线观看 | 麻豆视频在线免费看 | 亚洲视频第一页 | 日韩av成人免费看 | 国产无套视频 | 婷婷久草| 久久视频一区二区 | 国产精品 日韩精品 | 国产精品久久一区二区三区不卡 | 99久久精品费精品 | 91精品国产高清自在线观看 | 91精品国产乱码 | 久久免费a | 一级电影免费在线观看 | 国产精品原创在线 | 国产在线a免费观看 | 婷婷亚洲五月色综合 | 精品国产自在精品国产精野外直播 | 国产精品第52页 | 亚洲国产成人在线播放 | 五月天天色 | 免费看的视频 | 亚洲黄色在线观看 | 美女中文字幕 | 亚洲免费精品一区二区 | 国产成人精品午夜在线播放 | 久久久亚洲国产精品麻豆综合天堂 | 欧美视频日韩 | 在线观看一区视频 | 亚洲精品一区二区在线观看 | 天天干,夜夜爽 | 欧美坐爱视频 | 超碰公开97 | 免费在线播放黄色 | 91激情| 国内精品福利视频 | 91久久久久久久一区二区 | 欧美性色综合 | 亚洲欧洲av | 五月综合 | 91香蕉视频720p| 中文字幕人成乱码在线观看 | 一区二区精品在线观看 | 久久九九国产精品 | 日韩国产精品毛片 | 狠狠的操| 中文字幕在线观看免费观看 | 欧美日本啪啪无遮挡网站 | 99c视频高清免费观看 | 免费av影视| 在线观看亚洲 | 日韩欧美在线观看一区二区 | 夜夜操狠狠干 | 久久精彩免费视频 | 欧美日韩国产一二三区 | 中文在线字幕观看电影 | 久草剧场 | 欧美孕交vivoestv另类 | 久草在线在线精品观看 | 手机在线看a | 黄色aa久久| 91自拍91 | 免费午夜视频在线观看 | 久久最新网址 | 中文字幕 欧美性 | 色综合天天狠天天透天天伊人 | 国产精品日韩高清 | www.夜夜草 | 久久精品一二三区白丝高潮 | 在线观看免费黄视频 | 午夜久久福利影院 | 视频国产区| 久久 国产一区 | 久久天天拍 | 国产污视频在线观看 | 91在线观看欧美日韩 | 国产精品女同一区二区三区久久夜 | 欧美日韩一级久久久久久免费看 | 久久视频国产精品免费视频在线 | 毛片永久免费 | 久久国产精品一区二区三区四区 | 美女视频黄是免费的 | 国产日韩在线观看一区 | 久热久草在线 | 日韩久久精品一区二区三区下载 | 色吊丝在线永久观看最新版本 | 久久永久免费视频 | 亚洲人成人99网站 | 在线观看的黄色 | 精品成人免费 | 欧美色道| 91麻豆精品国产午夜天堂 | 久久免费成人精品视频 | 欧美一级黄色视屏 | 在线观看的av网站 | 日韩欧美69 | 国产91精品一区二区麻豆亚洲 | 久久久久久久久久久精 | 国产午夜精品一区 | 99热在线国产 | 9999精品| 97理论片 | 特级西西人体444是什么意思 | 亚洲 欧美 另类人妖 | 干 操 插 | 久久久久国产成人免费精品免费 | 国产精品女主播一区二区三区 | 久久久久欠精品国产毛片国产毛生 | 日韩中文字幕在线看 | 91av影视| 亚洲精品视频二区 | 奇米影视999| 伊人五月天综合 | 亚洲精品国偷自产在线91正片 | 亚洲精品在线观看av | 欧美精品午夜 | 日本中文字幕在线一区 | 久草观看视频 | 五月色婷 | sesese图片| www黄色大片| 91免费版成人 | 国产成人精品久久久 | 91精品国产99久久久久 | 97视频精品 | 欧美一级免费在线 | 一本一本久久aa综合精品 | 精品国产一区二区三区免费 | 天天草综合网 | 日韩av免费在线电影 | 最近免费中文字幕mv在线视频3 | 国产精品久久在线 | 在线观看亚洲电影 | 日韩电影在线看 | 成人性生交视频 | 亚洲精品国产自产拍在线观看 | 成年人国产在线观看 | 一区二区三区四区免费视频 | 日韩三级视频在线观看 | 久久久久欧美精品 | 色婷婷av在线 | 日韩色高清 | 黄网站免费大全入口 | 国产精品美女久久久网av | 婷婷免费在线视频 | 丁香花在线观看免费完整版视频 | 国内精品久久久久久久97牛牛 | 成人免费 在线播放 | 天天射一射 | 成年人电影毛片 | 国产精品午夜免费福利视频 | 在线视频1卡二卡三卡 | 日韩在线观看免费 | 九九视频在线观看视频6 | 亚洲三级精品 | 国产午夜视频在线观看 | 在线免费观看羞羞视频 | 免费观看v片在线观看 | 一区二区不卡在线观看 | 久久精品视频在线观看免费 | 国内少妇自拍视频一区 | 国产精品av电影 | 欧美福利精品 | 色偷偷人人澡久久超碰69 | 色综合激情久久 | 免费毛片aaaaaa | 正在播放 久久 | 美女视频久久 | 日韩精品一区二区三区不卡 | 亚洲在线视频网站 | 成人精品亚洲 | 日韩欧美一区二区在线 | 粉嫩av一区二区三区四区五区 | 国产喷水在线 | 欧美-第1页-屁屁影院 | 精品少妇一区二区三区在线 | www.69xx| 婷婷国产在线 | 韩国视频一区二区三区 | 精品国产亚洲日本 | av资源中文字幕 | 97天天干| 国产手机视频 | 丝袜av一区 | 中文字幕在线观看完整版 | 亚洲一区二区精品视频 | 一区二区三区四区免费视频 | 97成人精品视频在线播放 | 国产视频91在线 | 久久国产亚洲视频 | 韩国三级av在线 | www色网站| 免费黄色av| 91桃色免费视频 | 在线成人免费电影 | 玖玖国产精品视频 | 中文成人字幕 | 丝袜美女在线 | 欧美另类tv | 又黄又刺激的视频 | 国产一区在线观看免费 | 中文字幕中文 | 国产一区二区免费看 | 中文字幕之中文字幕 | 久久艹在线 | 又黄又爽又色无遮挡免费 | 黄色一二级片 | 久久久久色| 色婷婷欧美 | 狠狠色噜噜狠狠狠狠2021天天 | 91人人爱 | 超碰在线观看av | 久久久久久久电影 | 精品uu | 在线视频 国产 日韩 | 在线观看中文字幕视频 | 国产综合婷婷 | 91专区在线观看 | 中文字幕精品一区二区精品 | 欧美性春潮 | 国产高清精品在线 | 亚洲精品激情 | 99热国产精品 | 日本视频网 | 伊人手机在线 | 成人欧美一区二区三区在线观看 | 亚洲精品大全 | 四虎影视成人永久免费观看视频 | 久久国语露脸国产精品电影 | 五月婷婷激情六月 | 91成人免费观看视频 | 欧美性粗大hdvideo | 国产视频亚洲 | 国产片免费在线观看视频 | av免费在线网| 色av男人的天堂免费在线 | 亚洲欧美视频 | 最近久乱中文字幕 | 日日夜夜免费精品 | 免费观看91视频大全 | 免费电影一区二区三区 | 在线观看你懂的网址 | 99久久精品国产一区二区三区 | 69国产精品成人在线播放 | 国产精品大全 | 69绿帽绿奴3pvideos | 亚洲精品久久久久中文字幕二区 | 国产成人精品女人久久久 | 免费看污的网站 | 亚洲欧美综合精品久久成人 | 天天射天天艹 | 91精品秘密在线观看 | 国产在线观看网站 | 欧美成人理伦片 | 天堂av在线免费观看 | 日本乱视频 | 毛片美女网站 | 色橹橹欧美在线观看视频高清 | 六月色婷婷 | 午夜久久精品 | 韩国三级在线一区 | 亚洲精品欧洲精品 | 亚洲精品久久激情国产片 | 国产精品99久久久久久小说 | 日韩最新中文字幕 | 日本激情视频中文字幕 | www狠狠操| 在线观看黄色大片 | 人人爽人人做 | 六月丁香婷婷网 | 日日躁夜夜躁aaaaxxxx | 天天干,天天射,天天操,天天摸 | 亚洲精品456在线播放 | 中文字幕中文字幕在线中文字幕三区 | 久久精精品视频 | 日韩精品大片 | 国产高清在线a视频大全 | 天天综合人人 | 一区二区不卡高清 | 色综合久久精品 | 精品久久久久久亚洲 | 亚洲电影图片小说 | 亚洲国产精品va在线 | 国产一级片视频 | 成人网页在线免费观看 | 中文字幕丰满人伦在线 | 波多野结衣在线观看一区 | 久久99热精品这里久久精品 | 免费看的黄色网 | 亚欧洲精品视频在线观看 | 日日夜夜精品视频 | 国产精品乱码高清在线看 | 色资源在线观看 | 日韩三级视频在线看 | 丁香网五月天 | 99国产一区二区三精品乱码 | 日韩免费看的电影 | 四虎影视精品 | 精品免费国产一区二区三区四区 | 中文字幕在线观看不卡 | 日韩欧美在线国产 | 午夜免费福利片 | 视频一区二区视频 | 日本久久中文 | 在线你懂的视频 | 在线国产欧美 | 欧美-第1页-屁屁影院 | 97视频在线观看成人 | 精品成人久久 | 91成品人影院 | 久久在线观看视频 | 国产午夜精品一区二区三区四区 | 九九免费在线观看视频 | 欧美激情综合色 | 黄毛片在线观看 | 四虎影视欧美 | 欧美精品乱码99久久影院 | 国产精品永久在线观看 | 在线看v片成人 | 久热香蕉视频 | 亚洲成av人片一区二区梦乃 | 中文字幕乱在线伦视频中文字幕乱码在线 | 国产精品欧美久久 | 亚洲片在线观看 | 国产中文字幕一区二区三区 | 日韩精品一区二区三区在线播放 | av中文字幕在线观看网站 | 99久久精品费精品 | 丁香亚洲 | 午夜aaaa| 国产一区二区在线免费播放 | 日本一区二区三区免费观看 | 国产精品video爽爽爽爽 | 欧美日韩午夜爽爽 | 色综合久久88色综合天天人守婷 | h视频在线看 | 亚洲欧洲一级 | 我爱av激情网 | 国产亚洲一级高清 | 亚洲女欲精品久久久久久久18 | 国产成人精品一二三区 | 91香蕉国产 | 亚洲一二三久久 | 国产永久免费观看 | 日韩精品免费 | av在线播放免费 | 成人在线免费看视频 | 欧美精品久久久久久久久久久 | 天天干天天怕 | 天天综合91 | 大片网站久久 | 一区二区亚洲精品 | 日韩在线理论 | 啪啪肉肉污av国网站 | 欧美韩日在线 | 久要激情网 | 98久久| 精品国产免费人成在线观看 | 91精品国产九九九久久久亚洲 | 美女视频黄,久久 | 午夜黄色影院 | 午夜精品电影一区二区在线 | www.色五月| 久久高清免费观看 | 9992tv成人免费看片 | 久久精品电影 | 国产一区二区三区 在线 | 深爱五月激情网 | 福利一区二区 | 国产小视频在线 | 日韩精品高清视频 | 激情综合色综合久久综合 | 久草久草在线 | aa级黄色大片 | 最近中文字幕mv免费高清在线 | 中文字幕一区二区三区在线视频 | 视频1区2区 | 一区二区三区日韩在线 | 精品国产福利在线 | 久久大片 | 久久精品中文字幕一区二区三区 | 99久久精品国产亚洲 | 又黄又爽又无遮挡免费的网站 | 中文国产成人精品久久一 | 天天操天天射天天舔 | 视频在线观看日韩 | 手机av观看| 婷婷av在线 | 国产精品专区在线 | 国产成人免费观看久久久 | 欧美激情综合五月 | 色婷婷天天干 | 国产成人精品一区一区一区 | 国产福利免费在线观看 | 69视频永久免费观看 | 国产精品视频专区 | 黄色精品网站 | 操操爽 | 在线欧美中文字幕 | 五月天婷亚洲天综合网精品偷 | se婷婷| 国产成人一区二区三区电影 | 久久久精品国产免费观看一区二区 | 中文字幕国内精品 | 欧美日韩精品在线观看视频 | 久久中文视频 | 一区二区三区四区精品视频 | 91色九色 | av先锋中文字幕 | av三级在线播放 | av成人免费网站 | 久草视频2| 国产69精品久久久久久久久久 | 人人看人人 | 婷婷去俺也去六月色 | 欧美午夜性生活 | 天天爽天天碰狠狠添 | 人人爱人人舔 | 一二区精品| 4438全国亚洲精品在线观看视频 | 成 人 a v天堂 | а天堂中文最新一区二区三区 | 久久不卡电影 | 婷婷亚洲五月色综合 | 午夜性色 | 天天干天天综合 | 国产一区二区午夜 | 久久成人一区二区 | 免费在线激情电影 | 成人黄色大片在线免费观看 | 99精品国产99久久久久久97 | 99欧美精品 | 超碰人人超 | 91九色免费视频 | 六月激情 | 国产一区播放 | 麻豆激情电影 | 最新久久免费视频 | 亚洲欧洲视频 | 亚洲欧洲精品一区 | 欧美性天天 | 中文字幕婷婷 | 亚洲国产成人精品在线观看 | 在线视频 区 | 国产一二三在线视频 | 免费裸体视频网 | 日韩毛片在线免费观看 | 亚洲精品国精品久久99热一 | 日韩精品视频第一页 | 国产精品成人av在线 | 黄色av一级片 | 在线免费观看国产黄色 | 天天操夜操 | 九九热在线免费观看 | 黄色小网站在线 | 黄色大片日本 | 免费日韩 精品中文字幕视频在线 | 亚洲综合在线播放 | 天堂在线一区二区 | 人人草人人做 | 涩涩网站免费 | 一区二区三区在线观看免费视频 | 亚洲精品国产精品国自产观看浪潮 | 丁香花在线观看视频在线 | 中文字幕第一页在线视频 | 久久久久99精品国产片 | 999成人免费视频 | 久久不射电影院 | 亚洲精品午夜一区人人爽 | 在线观看视频色 | 美女网站黄在线观看 | 国产精品v欧美精品v日韩 | 99精品国产一区二区三区不卡 | 亚洲精品在线观看网站 | 1024久久| 国产成人综合图片 | 伊人黄色网 | 91视频免费看网站 | 精品一区二区在线看 | 黄色大片日本免费大片 | 91伊人影院 | 国产精品自在线拍国产 | www.天天成人国产电影 | 久久成人黄色 | 精品久久久久一区二区国产 | 9999免费视频 | 亚洲国产中文字幕在线观看 | 日韩精品一区在线观看 | 国产精品一区二区久久精品爱微奶 | 天天射天天操天天色 | 精品美女国产在线 | 日本久久久久久久久久 | 久久伊人精品一区二区三区 | 国产96精品 | 日韩成人免费在线电影 | 亚洲视频免费在线观看 | 91大神精品视频在线观看 | 精品国内自产拍在线观看视频 | 天天干天天干天天操 | 99tvdz@gmail.com | 久色免费视频 | 国产在线一区二区三区播放 | 免费人成在线观看网站 | 一区二区亚洲精品 | 成人午夜电影网站 | 国产精品igao视频网网址 | 国产精品久久久久久久久蜜臀 | 亚洲国产手机在线 | 亚洲精品国精品久久99热一 | 国产成人专区 | 最新av网址在线 | 在线观看亚洲免费视频 | 二区三区av| 成人免费视频网站在线观看 | 国产区欧美 | 97av在线视频免费播放 | 久久久人人爽 | 久久久久免费网 | 久久综合九色综合97婷婷女人 | 成年人在线观看免费视频 | 国产在线自 | 99视频在线免费看 | 久久国产精品99久久久久久丝袜 | 欧美日韩一区久久 | 91免费观看国产 | 国产日本在线观看 | 久久综合色影院 | 91精品视频观看 | 国内精品久久久久影院日本资源 | 91资源在线播放 | 欧美性生活一级片 | 久久男人中文字幕资源站 | 亚洲精品国产区 | av大全免费在线观看 | 全久久久久久久久久久电影 | a级黄色片视频 | 在线视频婷婷 | 黄色亚洲大片免费在线观看 | 中文字幕在线一二 | 香蕉影视在线观看 | 久久久久久免费网 | 18女毛片 | 五月婷香蕉久色在线看 | 狠狠狠色丁香婷婷综合激情 | 亚洲国产成人高清精品 | 91在线日韩 | 久久特级毛片 | 西西444www大胆高清图片 | 久久99亚洲精品久久 | 亚洲网久久 | 国产一级片网站 | 一区二区三区在线观看免费视频 | 国产色视频一区二区三区qq号 | 欧美日韩不卡在线 | 91免费高清在线观看 | 亚洲激情综合 | 久久视频二区 | 超碰97中文 | 91九色在线观看视频 | 狠狠躁18三区二区一区ai明星 | 成人97人人超碰人人99 | 久久66热这里只有精品 | 国产精品av免费 | av黄色大片 | 免费观看特级毛片 | 丁香导航 | 欧美一二三区播放 | 亚洲少妇激情 | 亚洲成成品网站 | 免费看v片网站 | 狠狠狠色丁香综合久久天下网 | 欧美日韩国产精品一区 | 91黄色免费网站 | 精品国产乱码久久久久久1区2匹 | 在线不卡的av | 五月天久久久 | av中文字幕在线电影 | 一区二区三区日韩在线观看 | 国产精品视频全国免费观看 | av黄色免费在线观看 | 91免费高清| 日韩免费久久 | 国产馆在线播放 | 欧美一区免费在线观看 | 国产亚洲情侣一区二区无 | av综合网址 | 狠狠色丁香九九婷婷综合五月 | 99久久精品日本一区二区免费 | 国产午夜三级一区二区三桃花影视 | 中文字幕日韩av | 午夜精品久久久久久久99水蜜桃 | 久久久久免费网 | 不卡av电影在线观看 | 国产伦精品一区二区三区高清 | 国产精品1区2区 | 亚洲第一av在线 | 国产色婷婷精品综合在线手机播放 | 国产精品久久久久一区二区三区 | 欧美午夜寂寞影院 | 99在线观看精品 | 精品国产精品国产偷麻豆 | 久久丁香 | 免费激情在线电影 | 天天干夜夜夜 | 一区二区三区在线影院 | 欧美另类视频 | 在线观看色视频 | 久久久人人人 | 波多野结衣在线观看视频 | 国产精品 日韩 欧美 | 亚洲三级网 | 亚洲视频分类 | 在线 高清 中文字幕 | 日韩欧美一区视频 | 国产人成看黄久久久久久久久 | 91久久偷偷做嫩草影院 | 久久久久久久99精品免费观看 | 超碰人人在线 | 亚洲一区二区三区四区在线视频 | 日韩r级在线 | 欧美激情综合五月色丁香 | 久草网站在线观看 | 色射色 | 久久久久久久久久免费视频 | 精品自拍av | 色综合久久99 | 免费久久网站 | 97国产超碰 | 欧美三级高清 | 欧美日韩一区二区免费在线观看 | 国产日韩视频在线观看 | 亚洲精品国偷拍自产在线观看 | 中文字幕在线免费97 | 亚洲成免费 | 九月婷婷综合网 | 97成人精品视频在线播放 | 国产一区 在线播放 | 色就干| 狠狠狠色丁香婷婷综合激情 | 天天操天天操天天操天天操天天操天天操 | 国产精品1024| 99精品视频免费在线观看 | 97视频免费| 免费视频网 | 亚洲久久视频 | 国产三级香港三韩国三级 | 久久午夜国产精品 | aav在线| 又黄又爽的免费高潮视频 | 麻豆免费视频观看 | 97色在线观看免费视频 | 1024久久| 伊人色播| 欧美精品国产综合久久 | 一本一本久久a久久精品综合妖精 | 96看片| 激情婷婷在线 | 亚洲一区二区视频在线播放 | 欧美激情视频一区二区三区 | 国产69精品久久99的直播节目 | 91精品啪在线观看国产 | av五月婷婷| 美女黄久久 | 亚洲影院国产 | 精品一区二区三区香蕉蜜桃 | 高清不卡毛片 | 婷婷伊人综合亚洲综合网 | 国产中文在线观看 | 色综合五月 | 色狠狠综合天天综合综合 | 亚洲激情校园春色 | 亚洲国产精品va在线看黑人 | 香蕉视频网址 | 成人小视频在线观看免费 | 国产一区二区三区在线免费观看 | 999久久久国产精品 高清av免费观看 | aⅴ视频在线 | 欧日韩在线视频 | 久草精品网 | 国产精品丝袜久久久久久久不卡 | 精品亚洲一区二区三区 | 91污在线 | 在线观看色网 | 欧美日韩免费观看一区=区三区 | 欧美日韩国语 | 日本久久综合网 | 日韩精品免费在线观看 | 91片在线观看 | 国产99久久久欧美黑人 | 国产精品久久久久婷婷 | 久草在线免 | 麻豆精品视频在线观看免费 | 日韩精品一区二区三区视频播放 | 中文字幕资源网 国产 | 免费看一级特黄a大片 | 最新日韩精品 | 日韩免费播放 | 超碰在线人| 四虎视频 | 夜夜夜夜爽 | 久久久久久综合 | 午夜久草 | 国产午夜精品理论片在线 | 五月婷婷综合网 | 久久高清国产视频 | 成人av.com | av在线之家电影网站 | 日韩欧美高清一区二区 | 欧美日韩一区二区三区在线免费观看 | 亚洲美女免费精品视频在线观看 | 久久五月精品 | 亚洲电影黄色 | 99免费看片| 视频在线观看亚洲 | 91禁在线看 | 国产精品视频区 | 国产精品av电影 | 四虎影视成人永久免费观看视频 | 欧美 日韩精品 | 在线视频欧美日韩 | 91在线你懂的 | 国产高h视频 | 色网站在线观看 | 久久伦理电影 | 超碰日韩 | 日韩国产欧美视频 | 成年美女黄网站色大片免费看 | 国产原创在线视频 | 亚洲亚洲精品在线观看 | 黄色一级性片 | 九七视频在线观看 | 久久不卡av| 日韩一区二区三免费高清在线观看 | 精品亚洲免费 | 日日操日日干 | a视频免费看| 国产在线观看免费观看 | 在线播放视频一区 | 国产99久久久久久免费看 | 婷婷av网 | 色瓜| 国产精品3| 亚洲免费观看视频 | 国产精品夜夜夜一区二区三区尤 | 国产亚洲婷婷免费 | 丝袜少妇在线 | 人人爽人人搞 | 成人黄色影片在线 | 黄色日本免费 | 色狠狠狠 | 国产一区二区精品久久91 | 久久国产成人午夜av影院宅 | 视频在线99 | 综合天天 | 精品久久久网 | 成人黄色大片网站 | 久久人人爽人人爽人人 | 蜜臀av麻豆 | 国产一区二区日本 | 在线视频一区观看 | 中文字幕av免费 | 99精品在线播放 | 国产xxxxx在线观看 | 国产无套精品久久久久久 | 久久国产精品第一页 | 操处女逼 | 又爽又黄又无遮挡网站动态图 | 中文字幕在线色 | 精品久久片 | 日韩有码在线播放 | 91精品福利在线 | 亚洲精品乱码久久久久久9色 | 91中文字幕在线观看 | 日韩久久精品一区 | 久久一级电影 | 婷婷亚洲综合五月天小说 | 国产高清视频 | 日韩国产在线观看 | 久久avav | 干 操 插| 中文字幕中文字幕在线中文字幕三区 | 日韩欧美一区二区在线观看 | 久久久久国产成人免费精品免费 | 国产糖心vlog在线观看 | 人人模人人爽 | 97在线观看 | 欧美在线aaa | 92精品国产成人观看免费 | 69av在线视频 | 五月色婷 | www.xxx.性狂虐 | 国产污视频在线观看 | 国产精品久久久电影 | 在线国产日韩 | 精品国产aⅴ一区二区三区 在线直播av | 黄色av一区 | 日韩av高清在线观看 | 国内精品在线一区 | 处女av在线 | 日本h视频在线观看 | 久久成人高清 | 高清av在线 | 视频成人永久免费视频 | 伊人久久婷婷 | 亚洲午夜av电影 | 亚洲欧洲久久久 | 久久不卡国产精品一区二区 | 国产一区二区电影在线观看 | 中文字幕区| 丁香色天天| 日日干夜夜爱 | 99九九免费视频 | 欧美精品免费在线 | 亚洲高清视频在线 | 色五丁香 | 精品亚洲免a | 91精品国产一区二区在线观看 | 亚洲国产精品电影在线观看 | 亚洲香蕉视频 | 激情深爱 | 人人爽人人爽人人爽 | 在线观看aa | 97精品国产91久久久久久久 | 不卡的av| 成人h电影| 中文字幕网站 | 日韩视频在线观看免费 | 欧美在线视频第一页 | 在线观看视频h | 亚洲伊人成综合网 | 国产精品日韩久久久久 | 久久精品国产第一区二区三区 | 碰碰影院 | 免费麻豆视频 | 亚洲精品在线免费观看视频 | 国产一二三区在线观看 | 国产91丝袜在线播放动漫 | av东方在线 | 亚洲黄色片在线 | 夜色资源站国产www在线视频 | 精品999| 丝袜美女视频网站 | 波多野结衣一区三区 | 免费看亚洲毛片 | 日韩欧美视频在线免费观看 | 成人久久久电影 | 黄色一级动作片 | 91爱看片 | 五月开心六月婷婷 | 最近日本字幕mv免费观看在线 | 亚洲精品视频一二三 | 日韩成人免费在线电影 | 国产精品专区h在线观看 | 九九久久国产精品 | 91九色网站 | 日韩动漫免费观看高清完整版在线观看 | 成人va天堂| 国产免费小视频 | 一级免费看 | 免费91麻豆精品国产自产在线观看 | 成人久久18免费网站麻豆 | 国产日韩欧美在线一区 | 亚洲乱码久久 | 天天舔夜夜操 | 日本公妇在线观看 | 九九视频在线播放 | avcom在线| 欧美午夜性生活 | japanesexxx乱女另类 | 久久新视频 | 中文字幕在线视频国产 | 久久婷婷色综合 | 成年人黄色免费视频 | 色欧美综合 | 人人爽人人爽av | 久久精品免视看 | 日韩精品中文字幕av | 国产国产人免费人成免费视频 | 国产尤物在线视频 | www.福利 | 久久久久久久久久影视 | 正在播放五月婷婷狠狠干 | 免费av网址大全 | 久久久久国产精品免费免费搜索 | 婷婷激情影院 | 久久久精品 一区二区三区 国产99视频在线观看 | 日本在线成人 | 国产视频久久 | 成人啪啪18免费游戏链接 | 色噜噜在线观看视频 | 国产偷国产偷亚洲清高 | 五月婷婷天堂 | 成人在线电影观看 | 久久久久久久精 | 久久艹在线观看 | 97精品国产97久久久久久久久久久久 | 一区二区伦理 | 久久1区 | 色吊丝在线永久观看最新版本 | 91资源在线免费观看 | 国产在线观看中文字幕 | www日韩高清| 精品国产一区二区三区久久久 | 热re99久久精品国产66热 | 波多野结衣一区 | 在线观看免费黄视频 | 麻豆成人小视频 | 日本久久成人中文字幕电影 | 国产黄网站在线观看 | 免费av影视 | 国产黄色大片 | 91亚洲精品久久久蜜桃借种 | 五月激情姐姐 | 亚洲男模gay裸体gay | 久久综合成人 | 国产精品九九视频 | 色狠狠一区二区 | 中文一区二区三区在线观看 | 五月开心激情 | 亚洲精选在线 | 一区二区视频在线播放 | 在线国产一区二区三区 | 久久久午夜剧场 | 国产精品久久久久久久久久久杏吧 | 国产福利午夜 | 国产精品久久久久久久久软件 | 91在线视频免费观看 | 一区二区视频电影在线观看 | 91大神免费视频 | 91九色在线视频观看 | 日本少妇视频 | 日韩一区二区三 | 夜夜操天天摸 | 国产最新91 | 国产一区二区久久久久 | 日本精品视频免费 | 探花系列在线 | 日本在线视频一区二区三区 | 欧美精品三级在线观看 | 亚洲精品影视 | 欧美精品久 | 日本中文乱码卡一卡二新区 | 色天天天| 又黄又爽又色无遮挡免费 | 久久国产热 | 欧美精品v国产精品v日韩精品 | 久久精品久久精品久久精品 | 欧美成人h版 | 国产精品久久久久久久久软件 | 免费成人黄色av | 欧美在线视频免费 | 久久久网址 | 国内精品久久久久影院日本资源 | 欧美另类xxx | 天天天天天天天操 | 国产精品尤物 | 五月综合激情网 | 国产精品麻豆99久久久久久 | 国产特级毛片aaaaaa高清 | 青青草久草在线 | 国产手机视频在线播放 | 国产成人精品一区二区三区福利 | 蜜桃视频日韩 | 日韩在线第一区 | 91大神在线看| 亚洲一区 影院 | 亚洲综合精品在线 | 亚洲国产成人av网 | 成人黄色影片在线 | www欧美日韩 | av在线电影网站 | 96视频免费在线观看 | 81国产精品久久久久久久久久 | 国产一二三区av | 国产精品久久在线 | 久久网页 | www色片| 久久久黄色 | 亚洲国产综合在线 | 久久视频在线观看中文字幕 | 国产午夜精品一区二区三区欧美 | 精品影院一区二区久久久 | 精品亚洲一区二区 | 日本中文字幕电影在线免费观看 | 黄色av电影网 | 亚洲国产免费网站 | av在线网站观看 | 黄色国产区 |