一区二区久久-一区二区三区www-一区二区三区久久-一区二区三区久久精品-麻豆国产一区二区在线观看-麻豆国产视频

關于CLR內存管理一些深層次的討論 [上篇]

  半年之前,PM讓我在部門內部進行一次關于“內存泄露”的專題分享,我為此準備了一份PPT。今天無意中將其翻出來,覺得里面提到的關于CLR下關于內存管理部分的內存還有點意思。為此,今天按照PPT的內容寫了一篇文章。本篇文章不會在討論那些我們熟悉的話題,比如“值類型引用類型具有怎樣的區(qū)別?”、“垃圾回收分為幾個步驟?”、“Finalizer和Dispose有何不同”、等等,而是討論一些不同的內容。整篇文章分上下兩篇,上篇主要談論的是“程序集(Assembly)和應用程序域(AppDomain)”。也許有的地方說的不是很正確,希望讀者不吝賜教。

  一、程序集與應用程序域

  何謂程序集(Assembly)?它是一個托管應用的基本的部署單元。一個程序集是自描述的(通過元數(shù)據(jù))、能夠實施版本策略和部署策略。我傾向于這樣的方式來定義程序集:“Assembly is a reusable, versionable, and self-describing building block of a CLR application.”從結構組成來看,一個程序集主要由三個部署組成:IL指令、元數(shù)據(jù)和資源。程序集的結構組成如下圖所示。

  那么什么又是應用程序域呢?從功能上講,通過應用程序域實現(xiàn)的隔離機制為托管代碼的執(zhí)行提供了一個安全的邊界。從與程序集的關系來講,我們可以將應用程序域看成是加載程序集的容器。只有相關的程序集被CLR加載到相應的應用程序域中,才談得上代碼的執(zhí)行。

基于應用程序域的隔離,歸根結底是內存的隔離。一個基本的反映就是:在一個應用程序域中創(chuàng)建的對象,不能直接在另一個應用程序域中使用。這中間需要有一個基本的跨應用程序域傳遞的機制,我們將這種機制稱之為“封送(Marshaling)”。具體來講,又具有兩種不同的封送方式:按值封送(MBV:Marshaling By Value )和按引用封送(MBR:Marshaling By Reference)。MBV主要采用序列化的方式,而MBR最典型的就是.ENT Remoting。

  二、系統(tǒng)程序域、共享程序域和默認程序域

  當托管應用被啟動后,在執(zhí)行第一句代碼之前,CLR會先后為我們創(chuàng)建三個應用程序域:系統(tǒng)程序域(System Domain)、共享程序域(Shared Domain)和默認程序域(Default Domain),它們分別具有不同的作用。

  • 系統(tǒng)程序域:系統(tǒng)程序域是第一個被創(chuàng)建的應用程序域,同時也是其他兩個應用程序域的創(chuàng)建者。在該程序域初始化過程中,由它將msCorLib.dll這個程序集(這是一個很重要的程序集,.NET類型系統(tǒng)最基本的類型定義其中)加載到共享程序域中。此外,駐留的字符串也被保存在此系統(tǒng)程序域中。系統(tǒng)程序域的一個主要的任務是追蹤其他所有應用程序域的狀態(tài),并負責加載和卸載它們;
  • 共享程序域:共享程序域主要用于保存以“中立域(Domain-neutral Domain )”加載的程序集容器。所謂“中立域 ”方式加載的程序集,就是說程序集并不被加載到當前的程序域中并被該程序域專用,而是加載到一個公共的程序域中被所有程序域共享。
  • 默認程序域:我們的托管程序最終就運行在該程序域中,默認程序域可以通過System.AppDomain表示。

  三、字符串的駐留

  上面的文字描述實際上透露一些重要的信息,其中一個就是字符串的駐留(String Interning)。關于字符串的駐留,我想大家都不陌生,所以在這里我就不作重復的介紹了。在這里,我只想討論一個問題:字符串的駐留是基于整個進程的,而不是僅僅基于某個應用程序域。

  從上面的描述我們知道,字符串對象和一般的引用類型對象具有很大的不同:字符串對象直接被保存到系統(tǒng)程序域中,而一般的引用類型對象我們都是最終保存在GC堆中。從某種意義上講,在字符串駐留機制下,字符串也是以“中立域”的方式被加載的,被駐留的字符串能夠被同一個進程下所有應用程序域所共享。

  那么,我們是否可以通過一些比較直觀的方式來驗證這一點。但是,我們不能直接編寫程序來比較兩個應用程序域中字符串是否是相同的引用,但是我們有一些間接的機制。我個人喜歡采用的方式是:加鎖。我們在運行于不同的應用程序域的代碼中對兩個字符串變量進行加鎖,如果程序運行的結果和對相同的對象加鎖一樣,那么就可以證明被枷鎖的兩個對象實際上是同一個對象。

  為了便于演示,我寫一個如下一個AppDomainContext,表示某個AppDomain對應的執(zhí)行上下文。AppDomainContext具有一個只讀的類型為AppDomain的屬性,該屬性通過構造函數(shù)執(zhí)行,最終在靜態(tài)方法NewContext被創(chuàng)建。我們調用Invoke方法讓指定的方法對應的應用程序域中執(zhí)行。

   1: public class AppDomainContext
   2: {
   3:     public AppDomain AppDomain { get; private set; }
   4:     private AppDomainContext(AppDomain appDomain)
   5:     {
   6:         this.AppDomain = appDomain;
   7:     }
   8:     public static AppDomainContext NewContext(string friendlyName)
   9:     {
  10:         return new AppDomainContext(AppDomain.CreateDomain(friendlyName));
  11:     }
  12:  
  13:     public void Invoke<T>(Action<T> action) where T : MarshalByRefObject
  14:     {
  15:         T instance = (T)this.AppDomain.CreateInstanceAndUnwrap(typeof(T).Assembly.FullName, typeof(T).FullName);
  16:         action.Invoke(instance);
  17:     }
  18: }

NET技術關于CLR內存管理一些深層次的討論 [上篇],轉載需保留來源!

鄭重聲明:本文版權歸原作者所有,轉載文章僅為傳播更多信息之目的,如作者信息標記有誤,請第一時間聯(lián)系我們修改或刪除,多謝。

主站蜘蛛池模板: 久久婷婷伊人 | 亚洲伊人久久大香线蕉苏妲己 | 国产高清国产专区国产精品 | 男女精品视频 | 国产精品999在线 | 91精品福利手机国产在线 | 欧美精品黄页在线观看视频 | 一区二区视频在线免费观看 | 亚洲欧美视频网站 | 亚洲伊人久久综合 | 国产中文字幕一区 | 久久久久亚洲香蕉网 | 四虎国产精品视频免费看 | 亚洲国产成人精彩精品 | 国产精品日韩欧美一区二区三区 | 国产极品在线观看 | 婷婷婷色| 精品国产夜色在线 | 四虎永久在线免费观看 | 视频一区二区三区自拍 | 久久午夜精品2区 | 91在线在线啪永久地址 | 成人a视频 | 亚洲国产成人精品小蝌蚪 | 久久是精品 | 色天天综合色天天害人害己 | 精品国产第一国产综合精品gif | 久99久热只有精品国产99 | 久久精品国产屋 | 男人女人无遮掩免费视频 | 国产欧美在线观看精品一区二区 | 亚洲综合久 | 国产成人精品一区二区 | 国产综合在线观看视频 | 91久久亚洲最新一本 | 久久影院中文字幕 | 49pao强力在线高清基地 | 99在线精品国产不卡在线观看 | 国产精品第100页 | 99在线精品免费视频九九视 | 2021国产精品成人免费视频 |