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

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

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

      .Net常識 值類型和引用類型

      值類型和引用類型是.net里面的一個基本概念

      在面試的時候也經(jīng)常遇到

      關(guān)于這個概念有很多誤解,經(jīng)常聽到下面的說法

      1.兩者的區(qū)別是值類型分配在堆棧上,引用類型分配在堆上

        這句話不對,至少不準(zhǔn)確

      2.值類型性能更好,

        這句話要考慮情況

       

      先補充一些背景資料

      常見的值類型有:大部分原生類型,例如int float long 各種自己定義的結(jié)構(gòu)體等等

      常見的引用類型有:string 各種Class 數(shù)組(包括int[]這種的)

      堆棧:在這里指的是執(zhí)行堆棧

      堆:在這里指的是托管堆,就是LOH+G0+G1+G2

       

      讓我們先來看看第一點:兩者的區(qū)別是值類型分配在堆棧上,引用類型分配在堆上

      1.假設(shè)在一個方法里面有一個語句是 var obj = new object(); 

      首先 new 出來的Object將被存放在堆中

      obj在堆棧上,其內(nèi)容是一個指針,指向new 出來的那個Object

      2.然后假設(shè)在一個方法里面有一個語句是 var i =1 ;

       這里的 i 在堆棧上, 其值是1  (int 類型)

      3.類中的值類型成員,例如以下一個定義

          public class ClassA
          {
              private int i = 1;
          }

      假設(shè)在一個方法里面有一個語句是 var obj = new ClassA(); 

      首先 new 出來的ClassA將被存放在堆中

      obj在堆棧上,其內(nèi)容是一個指針,指向new 出來的那個ClassA

      ClassA中的成員 i 這個時候也在堆上

      假設(shè)有一個有一個其他語句使用到ClassA.i 這個i的值才會被拷貝到堆棧上(大部分默認的情況)

      4.將引用類型放在堆棧上

       unsafe
                  {
                      var obj = stackalloc int[100];
                  }

      stackalloc是用來在堆棧上分配內(nèi)存的keyword

      上面的4個例子正好證明了 引用類型和值類型都可以存在在堆和堆棧上

      不過大部分時候都是情況1和2, 所以大部分引用類型都在堆上,大部分

       

      讓我們先來看看第二點:值類型性能更好

      就上面的情況1,2而言

      a.在取一個對象的時候,情況1先讀取obj的值, 這是一個地址,然后要重新讀取該地址的真正的對象Object

        情況2讀取obj的值,這就是真正的值了,所以相對數(shù)據(jù)比較快

      b.在堆中的對象受到GC的影響,需要額外的CPU資源;(堆棧中的對象,出棧以后釋放掉了)

      c.在堆中的對象需要等到GC后才被釋放,所以暫用內(nèi)存時間較久

      其他情況:

      1.考慮一些情況,裝箱拆箱;這是值類型在堆棧和對中拷貝時特有的操作,該操作還是非常消耗資源的

        那么如果無法避免裝箱拆箱,就要考慮避免使用值類型了

      2.值類型傳遞的時候每次都是值拷貝,如果某個值類型很大(例如自己定義的struct) 那么這個性能也是個問題;(而且還要考慮到堆棧有大小限制)

        所以一般情況下比較復(fù)雜的類型都只能用class

      3.許多時候,引用比較都比值比較來的快,因為引用比較只要看看兩個地址是否相等

        而值比較卻要考慮里面真實的值

       

      值類型和引用類型的區(qū)別其實從他們的名字上就看的出來

      在傳遞值類型的時候傳遞的是真實值,這也就意味著原來的值被復(fù)制了一份到新的位置

      而在傳遞引用類型的時候傳遞的是引用(地址),這里并沒有復(fù)制一份原來值的動作,因此兩個引用都指向一個對象

       

      Ref

      在沒有Ref的時候傳遞參數(shù),CLR會為每個參數(shù)弄一個臨時變量出來,存儲值類型的值或者是引用類型的指針

      這種情況下修改值類型或者引用類型的值不會影響到原來的值

      但是修改引用類型的成員會影響到原來的值,下面兩個例子分別是修改參數(shù)成員和修改參數(shù)本身

          public class ClassA
          {
              public string Name { get; set; }
          }
          class Program
          {
               
              static void Main(string[] args)
              {
                  ClassA a = new ClassA();
                  Test(a);
                  Console.WriteLine(a.Name);//這里會輸出mark
              }
      
              private static void Test(ClassA a)
              {
                  a.Name = "Mark";
              }
          }
      
          public class ClassA
          {
              public string Name { get; set; }
          }
          class Program
          {
               
              static void Main(string[] args)
              {
                  ClassA a = new ClassA();
                  Test(a);
                  Console.WriteLine(a.Name);//這里不會輸出Liu
              }
      
              private static void Test(ClassA a)
              {
                  a = new ClassA() { Name = "Liu" };
              }
          }
      

        

      在有REF的情況下傳遞參數(shù),CLR就會把原來的變量的地址傳遞過去,如果修改了該變量會影響到原來的成員

          public class ClassA
          {
              public string Name { get; set; }
          }
          class Program
          {
               
              static void Main(string[] args)
              {
                  ClassA a = new ClassA();
                  Test(ref a);
                  Console.WriteLine(a.Name);//這里會輸出Liu
              }
      
              private static void Test(ref ClassA a)
              {
                  a = new ClassA() { Name = "Liu" };
              }
          }
      

        

       

      備注1:如何確定一個對象在堆上或者是堆棧上

      剛才說的都是理論,這邊是驗證

      使用WinDBG+SOS附加到一個.net程序上;然后查看堆中的情況;

      具體指令就不說了,大家查看一下幫助

      posted on 2012-05-04 10:19  聽說讀寫  閱讀(1978)  評論(5)    收藏  舉報

      導(dǎo)航

      主站蜘蛛池模板: 国产首页一区二区不卡| 成人天堂资源www在线| 亚洲色www永久网站| 亚洲中文字幕无码专区| 亚洲国产欧美在线观看| 日韩一区二区三区在线观院| 国产无遮挡猛进猛出免费| 久热这里只精品99国产6-99RE视…| 宝应县| 成人一区二区三区在线午夜| 玩弄漂亮少妇高潮白浆| 国产网红女主播精品视频| 国产高清av首播原创麻豆| 日韩在线观看精品亚洲| 无码国产精品一区二区免费虚拟vr | 四虎影视www在线播放| 国产精品普通话国语对白露脸| 平罗县| 国产高清一区二区三区视频| 艳妇乳肉豪妇荡乳在线观看| 亚洲第三十四九中文字幕| 文水县| 色成年激情久久综合国产| 国产一二三五区不在卡| 日本高清一区免费中文视频| 日韩精品一区二区午夜成人版| 蜜臀av一区二区国产精品| 国产不卡精品一区二区三区| 天天做日日做天天添天天欢公交车 | 久久精品伊人狠狠大香网| 亚洲欧美综合人成在线| 97se综合| 精品91在线| 国产欧美日韩另类精彩视频| 欧美成人黄在线观看| 精品一区二区三区日韩版| 国产精品99久久久久久www| 国产精品十八禁在线观看| 国内精品久久久久影院薰衣草| 亚洲国产性夜夜综合| 开心五月深深爱天天天操|