日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營銷解決方案
淺析如何驗(yàn)證fixed關(guān)鍵字效果

本文主要是一種驗(yàn)證,對(duì)與fixed關(guān)鍵字操作的的驗(yàn)證,希望通過本文能讓大家對(duì)fixed關(guān)鍵字理解得更深入一些。同時(shí)也會(huì)分析程序員可能出現(xiàn)問題的一些壞習(xí)慣,希望對(duì)大家有所幫助。

創(chuàng)新互聯(lián)是一家專業(yè)提供謝通門企業(yè)網(wǎng)站建設(shè),專注與成都網(wǎng)站設(shè)計(jì)、成都網(wǎng)站制作、H5響應(yīng)式網(wǎng)站、小程序制作等業(yè)務(wù)。10年已為謝通門眾多企業(yè)、政府機(jī)構(gòu)等服務(wù)。創(chuàng)新互聯(lián)專業(yè)網(wǎng)站設(shè)計(jì)公司優(yōu)惠進(jìn)行中。

#T#

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

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

 
 
  1. public class SomeClass  
  2. {  
  3.     public int Field;  

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

 
 
  1. private static unsafe void GCOutOfFixedBlock()  
  2. {  
  3.     var a = new int[100];  
  4.     var c = new SomeClass();  
  5.  
  6.     fixed (int* ptr = &c.Field)  
  7.     {  
  8.         PrintAddress("Before GC", (int)ptr);  
  9.     }  
  10.  
  11.     GC.Collect(2);  
  12.  
  13.     fixed (int* ptr = &c.Field)  
  14.     {  
  15.         PrintAddress("After GC", (int)ptr);  
  16.     }  
  17. }  
  18.  
  19. private static void PrintAddress(string name, int address)  
  20. {  
  21.     Console.Write(name + ": 0x");  
  22.     Console.WriteLine(address.ToString("X"));  

在GCOutOfFixedBlock方法中,我們首先分配一個(gè)長度為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ì)將其回收——否則便無法看出地址改變的效果來。那么,我們重寫一段代碼:

 
 
  1. private static unsafe void GCInsideFixedBlock()  
  2. {  
  3.     var a = new int[100];  
  4.     var c = new SomeClass();  
  5.  
  6.     fixed (int* ptr = &c.Field)  
  7.     {  
  8.         PrintAddress("Before GC", (int)ptr);  
  9.         GC.Collect(2);  
  10.     }  
  11.  
  12.     fixed (int* ptr = &c.Field)  
  13.     {  
  14.         PrintAddress("After GC", (int)ptr);  
  15.     }  

結(jié)果如下:

Before GC: 0x1B558C0
After GC: 0x1B558C0

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

 
 
  1. private static unsafe void Mixed()  
  2. {  
  3.     var a = new int[100];  
  4.     var c1 = new SomeClass();  
  5.     var c2 = new SomeClass();  
  6.  
  7.     fixed (int* ptr1 = &c1.Field)  
  8.     {  
  9.         PrintAddress("Before GC", (int)ptr1);  
  10.     }  
  11.  
  12.     fixed (int* ptr2 = &c2.Field)  
  13.     {  
  14.         PrintAddress("Before GC (fixed)", (int)ptr2);  
  15.         GC.Collect(2);  
  16.     }  
  17.  
  18.     fixed (int* ptr1 = &c1.Field)  
  19.     {  
  20.         PrintAddress("After GC", (int)ptr1);  
  21.     }  
  22.  
  23.     fixed (int* ptr2 = &c2.Field)  
  24.     {  
  25.         PrintAddress("After GC (fixed)", (int)ptr2);  
  26.     }  

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


網(wǎng)頁題目:淺析如何驗(yàn)證fixed關(guān)鍵字效果
網(wǎng)站網(wǎng)址:http://www.5511xx.com/article/cceichs.html