叠放
的stack
是存储器,用于存储一个块local variables
和parameters
。随着函数的输入和退出,堆栈在逻辑上会增长和收缩。
请考虑以下方法:
public static int Factorial (int x)
{
if (x == 0)
{
return 1;
}
return x * Factorial (x - 1);
}
此方法是递归的,这意味着它会自行调用。每次输入该方法时,都会在堆栈上分配一个新的int,并且每次该方法退出时,都会释放int。
堆
- 堆是
objects
(即reference-type instances
)驻留的内存块。每当创建新对象时,都会在堆上分配该对象,并返回对该对象的引用。在程序执行期间,随着创建新对象,堆开始填充。运行时具有垃圾收集器,该垃圾收集器会定期从堆中取消分配对象,因此程序不会运行Out Of Memory
。一旦对象本身未被任何对象引用,则该对象有资格进行释放alive
。
- 堆也存储
static fields
。与在堆上分配的对象(可能会被垃圾回收)不同these live until the application domain is torn down
。
请考虑以下方法:
using System;
using System.Text;
class Test
{
public static void Main()
{
StringBuilder ref1 = new StringBuilder ("object1");
Console.WriteLine (ref1);
StringBuilder ref2 = new StringBuilder ("object2");
StringBuilder ref3 = ref2;
Console.WriteLine (ref3);
}
}
在上面的示例中,我们首先创建一个由变量ref1引用的StringBuilder对象,然后写出其内容。然后,该StringBuilder对象立即可以进行垃圾回收,因为随后没有任何人使用它。然后,我们创建另一个由变量ref2引用的StringBuilder,并将该引用复制到ref3。即使在那之后没有使用ref2,ref3也会使该StringBuilder对象保持活动状态-确保在我们完成使用ref3之前,它不符合收集条件。
值类型实例(和对象引用)位于声明该变量的任何位置。如果实例被声明为类类型中的字段或数组元素,则该实例将驻留在堆中。