CLR的简单理解
????????CLR加載程序生成進程,一個進程中可以存在多個線程,當創(chuàng)建一個線程時,會分配1Mb的空間,也就是線程的棧空間,對應jvm的虛擬機堆棧,是線程執(zhí)行過程中用到的工作內存。這片內存用于方法傳遞實參,并存儲方法內部定義的局部變量,棧是從高位地址向低位地址構建。棧是由操作系統(tǒng)直接管理,不受GC控制,當執(zhí)行的方法退出后,棧中的存儲會自動釋放。棧的效率很高,但存儲空間有限。
????????對象的數(shù)據存儲在堆上,堆上的數(shù)據是所有線程共享的,堆根據類型又分為:GC堆、加載堆(Loader Heap)、大對象(LOH)堆。當對象實例大小小于85000字節(jié)時,該對象會被分配到GC堆上,GC回收主要是回收這一片區(qū)域,回收過后會進行壓縮。當對象實例大小大于85000個字節(jié)時,會被分配到LOH堆,只有GC進行完全回收時這片區(qū)域的數(shù)據才會被回收,且回收后不會壓縮。
????????加載堆(Loader Heap)用來存儲類型的元數(shù)據,也就是類的Type信息,反射的時候就是用到這里面的信息。每個類在加載堆中對應一個方法表(Method Table),里面記錄該類的元數(shù)據信息,比如基類型、靜態(tài)字段、繼承的接口、所有的方法等。加載堆不受GC控制,不會被回收,其生命周期是從創(chuàng)建(第一次使用)直到AppDomain卸載。
????????當我們在程序中new一個對象時,會根據這個對象的大小(字段數(shù)據等)在GC堆中生成這個對象的內存空間,其中字段數(shù)據直接在這個對象空間中,同時這個對象會包含兩個引用:TypeHandle和SyncBlockIndex。其中TypeHandle指向加載堆(Loader Heap)中的方法表(Method Table),SyncBlockIndex指針指向Synchronization Block的內存塊,用于在多線程環(huán)境下對實例對象的同步操作。當這些都準備好以后,會將GC堆中的內存地址返回給棧中該變量,這里也是整個new的過程。
????????這里有必要對加載堆(Loader Heap)做下補充,其實在類第一次使用(不一定是new)的時候,類的元數(shù)據信息就會被放到加載堆(Loader Heap)中。當真正new一個對象的時候,其實加載堆(Loader Heap)中已經有該類的元數(shù)據信息,如果沒有,也會先創(chuàng)建。然后再將這個對象的TypeHandle和加載堆中的該類型的MethodTable對應起來。
????????以上所有描述,可參考下圖:
?
總結
- 上一篇: 把Autofac玩的和java Spri
- 下一篇: 我们真的需要JWT吗?