<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12
      代碼改變世界

      驗(yàn)證fixed關(guān)鍵字效果的小實(shí)驗(yàn)

      2009-11-29 21:11  Jeffrey Zhao  閱讀(5798)  評(píng)論(35)    收藏  舉報(bào)

      之前談到String連接操作的性能,其中會(huì)涉及到unsafe操作,而unsafe操作必然會(huì)涉及到指針,于是fixed關(guān)鍵字也應(yīng)運(yùn)而生。fixed關(guān)鍵字是用來(lái)pin住一個(gè)引用地址的,因?yàn)槲覀冎繡LR的垃圾收集器會(huì)改變某些對(duì)象的地址,因此在改變地址之后指向那些對(duì)象的引用就要隨之改變。這種改變是對(duì)于程序員來(lái)說(shuō)是無(wú)意識(shí)的,因此在指針操作中是不允許的。否則,我們之前已經(jīng)保留下的地址,在GC后就無(wú)法找到我們所需要的對(duì)象。現(xiàn)在就來(lái)我們就來(lái)做一個(gè)小實(shí)驗(yàn),驗(yàn)證fixed關(guān)鍵字的效果。

      當(dāng)然,這個(gè)實(shí)驗(yàn)很簡(jiǎn)單,簡(jiǎn)單地可能會(huì)讓您笑話。首先我們來(lái)準(zhǔn)備一個(gè)SomeClass類(lèi):

      public class SomeClass
      {
          public int Field;
      }

      然后準(zhǔn)備一段代碼:

      private static unsafe void GCOutOfFixedBlock()
      {
          var a = new int[100];
          var c = new SomeClass();
      
          fixed (int* ptr = &c.Field)
          {
              PrintAddress("Before GC", (int)ptr);
          }
      
          GC.Collect(2);
      
          fixed (int* ptr = &c.Field)
          {
              PrintAddress("After GC", (int)ptr);
          }
      }
      
      private static void PrintAddress(string name, int address)
      {
          Console.Write(name + ": 0x");
          Console.WriteLine(address.ToString("X"));
      }

      在GCOutOfFixedBlock方法中,我們首先分配一個(gè)長(zhǎng)度為100的int數(shù)組,然后新建一個(gè)SomeClass對(duì)象。新建數(shù)組的目的在于制造“垃圾”,目的是在調(diào)用GC.Collect方法時(shí)改變SomeClass對(duì)象在堆中的位置。由于垃圾回收發(fā)生在fixed代碼塊之外,這樣我們前后兩次打印出的值便是不同的:

      Before GC: 0x1A058C0
      After GC: 0x1975DF4

      值得注意的是,這段代碼必須在Release模式下進(jìn)行編譯,讓CLR執(zhí)行代碼時(shí)進(jìn)行優(yōu)化,這樣CLR便會(huì)在垃圾回收時(shí)發(fā)現(xiàn)a數(shù)組已經(jīng)是垃圾了(因?yàn)楹竺娴拇a不會(huì)用它),于是會(huì)將其回收——否則便無(wú)法看出地址改變的效果來(lái)。那么,我們重寫(xiě)一段代碼:

      private static unsafe void GCInsideFixedBlock()
      {
          var a = new int[100];
          var c = new SomeClass();
      
          fixed (int* ptr = &c.Field)
          {
              PrintAddress("Before GC", (int)ptr);
              GC.Collect(2);
          }
      
          fixed (int* ptr = &c.Field)
          {
              PrintAddress("After GC", (int)ptr);
          }
      }

      結(jié)果如下:

      Before GC: 0x1B558C0
      After GC: 0x1B558C0

      由于GC發(fā)生在fixed代碼塊內(nèi)部,因此c對(duì)象被pin在堆上了,于是GC前后c對(duì)象的地址沒(méi)變,這就是fixed的作用。那么,下面這段代碼運(yùn)行結(jié)果是什么呢?

      private static unsafe void Mixed()
      {
          var a = new int[100];
          var c1 = new SomeClass();
          var c2 = new SomeClass();
      
          fixed (int* ptr1 = &c1.Field)
          {
              PrintAddress("Before GC", (int)ptr1);
          }
      
          fixed (int* ptr2 = &c2.Field)
          {
              PrintAddress("Before GC (fixed)", (int)ptr2);
              GC.Collect(2);
          }
      
          fixed (int* ptr1 = &c1.Field)
          {
              PrintAddress("After GC", (int)ptr1);
          }
      
          fixed (int* ptr2 = &c2.Field)
          {
              PrintAddress("After GC (fixed)", (int)ptr2);
          }
      }

      至于為什么是這個(gè)結(jié)果,那便和CLR實(shí)現(xiàn)方式有關(guān)了具體參見(jiàn)文章下方討論。

      主站蜘蛛池模板: 二区三区亚洲精品国产| 精品人妻伦一二三区久久aaa片| 四虎国产精品永久在线下载| 国产无遮挡吃胸膜奶免费看| 在线看国产精品自拍内射| 日韩在线观看精品亚洲| 三级国产三级在线| 军人粗大的内捧猛烈进出视频| 色偷偷亚洲女人天堂观看| 久久精品国产亚洲欧美| 亚洲欧美日韩在线码| 四虎成人高清永久免费看| 亚洲中文字幕第二十三页| 爆乳日韩尤物无码一区| 亚洲国产一区二区精品专| 丝袜高潮流白浆潮喷在线播放| 人妻系列无码专区免费| 久爱www人成免费网站| 日韩成人午夜精品久久高潮| 国产精品自拍午夜福利| 少妇做爰免费视看片| 国产精品国三级国产专区| 2021国产成人精品久久 | 人人干人人噪人人摸| 91老肥熟女九色老女人| 国产精品入口中文字幕| 亚洲中文字幕人妻系列| 亚洲一区二区av免费| 视频免费完整版在线播放| 精品国产一区二区三区四区| 精品国产精品中文字幕| 疯狂做受XXXX高潮国产| 东兰县| 日本人妻巨大乳挤奶水免费| 国产精品先锋资源站先锋影院| 中文字幕国产精品自拍| 国产麻豆精品手机在线观看| 日韩精品一区二区三区中文| 国产永久免费高清在线| 亚洲av中文乱码一区二| 久久精品天天中文字幕人妻|