标签:int 空间 引用类型 mem string size air html 结构
原文链接:https://jonskeet.uk/csharp/memory.html
人们在理解值类型和引用类型之间的差异时因为“值类型在栈上分配,引用类型在堆上分配”这句话造成了很多混乱。这完全是不对的,本文试图澄清这个问题。
变量中有什么?
理解.NET中内存工作方式的关键是理解变量是什么,以及它的值是什么。在最基本的层面上,变量是变量名和内存之间的关联。变量的值是与之关联的内存中的内容。该值占用内存空间的大小和值的解释取决于变量的类型 - 这正是值类型和引用类型之间的差异所在。
引用类型变量的值始终是引用或null
。如果是引用,则它必须是与其变量类型兼容的对象的引用。例如,以Stream s声明的变量s的值是null或Stream类型(或其兼容类型)实例的引用。引用类型变量所占内存空间的大小是引用的大小,引用的大小在32位模式下固定为4个字节,在64位模式下固定为8个字节。
值类型变量的值始终是其对象本身的值。例如,对于给定的结构:
struct PairOfInts { public int a; public int b; }
以PairOfInts pair声明的变量pair的值是整数对本身,而不是对一对整数的引用。其所占内存空间则是两个整数的大小,即8个字节。请注意,值类型变量永远不能赋值为null - 因为这没有任何意义,值类型变量不是一个引用。
那么东西存放在哪里?
变量的分配位置取决于声明它的上下文:
上述规则有几个例外:在使用匿名方法时的外部变量和迭代器中的局部变量会由编译器优化为其它类型的实例字段,这些变量会转移到堆中分配。
举个例子
上述文字描述可能听起来有点复杂,但一个完整的例子可以让事情更清楚一些:
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/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
标签:int 空间 引用类型 mem string size air html 结构
原文地址:https://www.cnblogs.com/minotauros/p/11254159.html