關於CLR記憶體管理一些深層次的討論 上篇

2022-01-16 20:35:15 字數 2801 閱讀 6298

一、程式集與應用程式域

那麼什麼又是應用程式域呢?從功能上講,通過應用程式域實現的隔離機制為託管**的執行提供了乙個安全的邊界。從與程式集的關係來講,我們可以將應用程式域看成是引導程式集的容器。只有相關的程式集被clr載入到相應的應用程式域中,才談得上**的執行。

基於應用程式域的隔離,歸根結底是記憶體的隔離。乙個基本的反映就是:在乙個應用程式域中建立的物件,不能直接在另乙個應用程式域中使用。這中間需要有乙個基本的跨應用程式域傳遞的機制,我們將這種機制稱之為「封送(marshaling)」。具體來講,又具有兩種不同的封送方式:按值封送(mbv:marshaling by value )和按引用封送(mbr:marshaling by reference)。mbv主要採用序列化的方式,而mbr最典型的就是.ent remoting。

當託管應用被啟動後,在執行第一句**之前,clr會先後為我們建立三個應用程式域:系統程式域(system domain)、共享程式域(shared domain)和預設程式域(default domain),它們分別具有不同的作用。

上面的文字描述實際上透露一些重要的資訊,其中乙個就是字串的駐留(string interning)。關於字串的駐留,我想大家都不陌生,所以在這裡我就不作重複的介紹了。在這裡,我只想討論乙個問題:字串的駐留是基於整個程序的,而不是僅僅基於某個應用程式域。

從上面的描述我們知道,字串物件和一般的引用型別物件具有很大的不同:字串物件直接被儲存到系統程式域中,而一般的引用型別物件我們都是最終儲存在gc堆中。從某種意義上講,在字串駐留機制下,字串也是以「中立域」的方式被載入的,被駐留的字串能夠被同乙個程序下所有應用程式域所共享。

public

2:
8:

public9:

12:
13:

public

void invoke(actionaction) where t : marshalbyrefobject

14:
18: }
public

class objectlock : marshalbyrefobject

2:
10:     }
11:

public

void checklock(object objecttolock)

12:
17:

else

18:
21:     }
22: }
static

void main(string args)

2:
輸出結果:

2: 2: [bar] the object is locked.
上面的介紹同時說明乙個問題:千萬不要對乙個字串物件加鎖。

2:
5: }
然後我們修改之前的程式,將對字串加鎖替換在對foo型別(typeof(foo))加鎖。從輸出結果我們可以看出,在bar程式域中使用的foo型別並沒有被鎖住,從而證明兩個程式域(foo和bar)使用的同乙個型別並不是type物件,因為對應的程式集是以獨佔的方式載入的。

static

void main(string args)

2:
輸出結果:

2: [bar] the object is not locked.
但是,如果我們將加鎖和鎖定檢驗的typeof(foo)替換成typeof(int),結果就完全不一樣了。不同的結果說明了mscorlib.dll採用了不同於上面的程式集載入方式,以中立域方法的載入方式決定在任何應用程式域中使用的型別都是同乙個type物件。

static

void main(string args)

2:
輸出結果:

2: [bar] the object is locked.
我想到這裡有人會問乙個問題:「我們自定義的程式集可以像mscorlib.dll一樣以中立域的方式共享載入嗎?」。對於控制台應用,你只需要在main方法上應用loaderoptimizationattribute特性,並指定loaderoptimization為multidomain即可。比如,還是採用對foo型別foo型別(typeof(foo))物件加鎖,這次我們在main方法上應用了這樣的特性:[loaderoptimization(loaderoptimization.multidomain)]。輸出的結果就與對int32型別物件加鎖一樣。

[loaderoptimization(loaderoptimization.multidomain)]

2:

static

void main(string args)

3:
輸出結果:

2: [bar] the object is locked.
又乙個關於加鎖的注意:謹慎地對type物件進行加鎖。

關於clr記憶體管理一些深層次的討論[上篇]

關於clr記憶體管理一些深層次的討論[下篇]

關於CLR記憶體管理一些深層次的討論 上篇

一 程式集與應用程式域 基於應用程式域的隔離,歸根結底是記憶體的隔離。乙個基本的反映就是 在乙個應用程式域中建立的物件,不能直接在另乙個應用程式域中使用。這中間需要有乙個基本的跨應用程式域傳遞的機制,我們將這種機制稱之為 封送 marshaling 具體來講,又具有兩種不同的封送方式 按值封送 mb...

關於linux棧的乙個深層次的問題

記憶體不用白不用,何必在一開始就限制棧的大小,linux的機制是盡量多盡量緊湊的使用虛擬記憶體,原則就是你現在不用我就用,沒有預留的概念,當然你可以通過系統呼叫實現預留,就像glibc的堆管理那樣,這裡所說的完全是針對於作業系統核心的,使用者空間程式完全可以向作業系統通過brk或者mmap實現使用者...

關於linux棧的乙個深層次的問題

原文 記憶體不用白不用,何必在一開始就限制棧的大小,linux的機制是盡量多盡量緊湊的使用虛擬記憶體,原則就是你現在不用我就用,沒有預留的概念,當然你可以通過系統呼叫實現預留,就像glibc的堆管理那樣,這裡所說的完全是針對於作業系統核心的,使用者空間程式完全可以向作業系統通過brk或者mmap實現...