原文連接:https://jonskeet.uk/csharp/memory.htmlhtml
人們在理解值類型和引用類型之間的差別時由於「值類型在棧上分配,引用類型在堆上分配」這句話形成了不少混亂。這徹底是不對的,本文試圖澄清這個問題。優化
變量中有什麼?spa
理解.NET中內存工做方式的關鍵是理解變量是什麼,以及它的值是什麼。在最基本的層面上,變量是變量名和內存之間的關聯。變量的值是與之關聯的內存中的內容。該值佔用內存空間的大小和值的解釋取決於變量的類型 - 這正是值類型和引用類型之間的差別所在。指針
引用類型變量的值始終是引用或null
。若是是引用,則它必須是與其變量類型兼容的對象的引用。例如,以Stream s聲明的變量s的值是null或Stream類型(或其兼容類型)實例的引用。引用類型變量所佔內存空間的大小是引用的大小,引用的大小在32位模式下固定爲4個字節,在64位模式下固定爲8個字節。code
值類型變量的值始終是其對象自己的值。例如,對於給定的結構:htm
struct PairOfInts { public int a; public int b; }
以PairOfInts pair聲明的變量pair的值是整數對自己,而不是對一對整數的引用。其所佔內存空間則是兩個整數的大小,即8個字節。請注意,值類型變量永遠不能賦值爲null - 由於這沒有任何意義,值類型變量不是一個引用。對象
那麼東西存放在哪裏? blog
變量的分配位置取決於聲明它的上下文:內存
上述規則有幾個例外:在使用匿名方法時的外部變量和迭代器中的局部變量會由編譯器優化爲其它類型的實例字段,這些變量會轉移到堆中分配。字符串
舉個例子
上述文字描述可能聽起來有點複雜,但一個完整的例子可讓事情更清楚一些:
using System; struct PairOfInts { static int counter = 0; public int a; public int b; internal PairOfInts(int x, int y) { A = x; B = y; counter++; } } class Test { PairOfInts pair; string name; Test(PairOfInts p, string s, int x) { pair = p; name = s; pair.a + = x; } static void Main() { PairOfInts z = new PairOfInts(1, 2); Test t1 = new Test(z, "first", 1); Test t2 = new Test(z, "second", 2); Test t3 = null; Test t4 = t1; //XXX } }
讓咱們看一下標記「XXX」位置時內存中的內容。
若是您以爲閱讀本文對您有幫助,請點一下「推薦」按鈕,您的承認是我寫做的最大動力!
做者:Minotauros
出處:https://www.cnblogs.com/minotauros/
本文版權歸做者和博客園共有,歡迎轉載,但未經做者贊成必須保留此段聲明,且在文章頁面明顯位置給出原文鏈接,不然保留追究法律責任的權利。