close

淺析如何驗證fixed關鍵字效果

 

對與fixed關鍵字操作的的驗證,希望通過本文能讓大家對fixed關鍵字理解得更深入一些。同時也會分析程式師可能出現問題的一些壞習慣,希望對大家有所説明。

實作CLR存儲過程十四步
趣談CLR集成性能設計選擇
全面分析CLR與作業系統關係
全面講解CLR安全性
代碼演示CLR Via C#調用靜態構造函數

之前談到String連接操作的性能,其中會涉及到unsafe操作,而unsafe操作必然會涉及到指標,關鍵字廣告於是fixed關鍵字也應運而生。fixed關鍵字是用來pin住一個引用位址的,因為我們知道CLR的垃圾收集器會改變某些物件的位址,因此在改變位址之後指向那些物件的引用就要隨之改變。這種改變是對於程式師來說是無意識的,因此在指標操作中是不允許的。否則,我們之前已經保留下的位址,在GC後就無法找到我們所需要的物件。現在就來我們就來做一個小實驗,驗證fixed關鍵字的效果。

當然,這個實驗很簡單,簡單地可能會讓您笑話。首先我們來準備一個SomeClass類:

在GCOutOfFixedBlock方法中,我們首先分配一個長度為100的int陣列,然後新建一個SomeClass物件。新建陣列的目的在於製造“垃圾”,目的是在調用GC.Collect方法時改變SomeClass物件在堆中的位置。由於垃圾回收發生在fixed代碼塊之外,關鍵字廣告 這樣我們前後兩次列印出的值便是不同的:

Before GC: 0x1A058C0
After GC: 0x1975DF4

值得注意的是,這段代碼必須在Release模式下進行編譯,讓CLR執行代碼時進行優化,這樣CLR便會在垃圾回收時發現a陣列已經是垃圾了(因為後面的代碼不會用它),於是會將其回收——否則便無法看出位址改變的效果來。那麼,我們重寫一段代碼:
結果如下:

Before GC: 0x1B558C0
After GC: 0x1B558C0

由於GC發生在fixed代碼塊內部,因此c物件被pin在堆上了,關鍵字廣告於是GC前後c物件的位址沒變,這就是fixed的作用。那麼,下麵這段代碼運行結果是什麼呢?

至於為什麼是這個結果,那便和CLR實現方式有關了。

arrow
arrow
    全站熱搜

    tupian11 發表在 痞客邦 留言(0) 人氣()