声明变量的内部机制 下图揭示了声明一个变量时的内部机制其中分配的内存类型依据你的变量类型。.NET中有两种类型的内存栈内存和堆内存。在接下来的内容中我们会了解到这两种类型的详细内容。栈和堆为了明白什么是栈和堆先让我们看下下面示例代码的内部机制12345678publicvoidMethod1(){// Line 1inti4;// Line 2inty2;//Line 3class1 cls1 newclass1();}这里一共有3行代码。让我们一下逐行看一下它们是如何执行的第1行当这行代码执行时编译器为它分配一小块栈内存。运行时栈负责提供程序所需的内存第2行程序继续执行。如同名字一样栈在第一块内存的顶部分配了一块内存。你也可以认为是模块或零件一块一块叠起来内存的分配与释放遵循后进先出(后进先出)逻辑换句话说内存只能在示例中i内存块的顶部分配或释放。第3行在第3行我们创建了一个对象。当该行执行时编译器在站上创建了一个指针真实的对象存储在另一种叫“堆”的内存中。堆并不跟踪运行内存它更像一堆随时可以访问的对象。堆用于动态分配内存。这里需要着重说明的是引用指针是分配在栈上。声明Class1 cls1时并不会给Class1的实例分配内存而是分配一个栈变量cls1并设置为null,然后把它指向“堆”。退出方法当方法退出时它释放了栈上所有内存变量。换句话说栈上所有的Int变量都依据后进先出的逻辑被释放掉了。要注意此时不会释放堆内存这种内存稍后会被“垃圾收集器”释放。现在可能会有很多朋友奇怪为什么要分配2种内存而不是仅用一种内存。如果仔细观察你会发现基本类型并不复杂他们值包含简单的值如i0。对象数据类型很复杂它们会引用其它对象或基本类型。换句话说它要保持其它多种多样的引用而每种类型必须存在内存中。对象类型需要动态内存而基本类型需要静态内存。如果需要分配动态内存那么就分配到堆上反之在栈上。值类型与引用类型现在我们明白了栈和堆接下来看值类型和引用类型。值类型的数据和内存在同一个位置而引用类型是一个指向内存的指针。下面示例是一个整形数据类型变量i被赋给另一个整形数据类型变量j。它们的内存值都分配在栈上。当我们把一个int值分配给另外一个int值时需要创建一个完全不同的拷贝。换句话说你可以改变其中任何一个而不会影响另外一个。这种数据类型被称为值类型。当我们创建一个对象并把一个对象赋给另外一个对象时它们的指针指向相同的内存(如下图当我们把obj赋给obj1时它们指向相同的内存)。换句话说我们改变其中一个会影响到另外一个这种类型称为引用类型。那么那种类型是值类型和引用类型呢在.NET中依据数据类型变量被分配到堆或栈上。“string”和Object是引用类型其他基本类型被分配到栈上是值类型如下图装箱与拆箱通过上面学习我们学到了很多有用的东西其中最有用的是明白了当把数据从栈移动到堆上时会有性能损失。如下图实例当我们把一个值类型装箱为引用类型时数据从栈移动到堆上。反之数据从堆移动到栈上。这种在堆和栈之间的移动带来了性能的损失。数据从值类型转变为引用类型的过程称为“装箱”反之为“拆箱”。如果编译上面的代码在ILDASM中看IL代码就会发下如何进行装箱拆箱操作的如下