C# 7.0 核心技术指南 (37):C#语言基础 2.8.1

阅读数:10 2019 年 11 月 30 日 23:44

C# 7.0核心技术指南(37):C#语言基础 2.8.1

(栈和堆)

内容简介
本书前三章将集中介绍 C#语言。首先介绍基本的语法、类型和变量。而后会介绍一些高级的特性,如不安全代码以及预处理指令。如果你是 C#语言的初学者,请循序渐进地阅读这些章节。
其余各章则涵盖了.NET Framework 的核心功能,包括 LINQ、XML、集合、并发、I/O 和网络、内存管理、反射、动态编程、特性、安全、应用程序域和原生互操作性等主题。第 6 章和第 7 章是后续主题的基础,除这两章之外,其余各章可以按照需要以任何顺序阅读。LINQ 相关的三个章节好按顺序阅读。其中的一些章节需要一些并发相关的知识,这些知识将在第 14 章中介绍。

栈和堆是存储变量和常量的地方。它们分别具有不同的生命周期语义。

2.8.1.1 栈

栈是存储局部变量和参数的内存块。逻辑上,栈会在函数进入和退出时增加或减少。考虑下面的方法(为了避免干扰,该范例省略了输入参数检查):

复制代码
static int Factorial (int x)
{
if (x == 0) return 1;
return x * Factorial (x-1);
}

这个方法是递归的,即它调用其自身。每一次进入这个方法的时候,就在栈上分配一个新的 int,而每一次离开这个方法,就会释放一个 int。

2.8.1.2 堆

堆是保存对象(例如引用类型的实例)的内存块。新创建的对象会分配在堆上并返回其引用。程序执行过程中,堆就被新创建的对象不断填充。.NET 运行时的垃圾回收器会定期从堆上释放对象,因此应用程序不会内存不足。只要对象没有被“存活”的对象引用,它就可以被释放。

下面的例子中,我们创建了一个 StringBuilder 对象并将其引用赋值给 ref1 变量,之后在其中写入内容。StringBuilder 对象在后续没有使用的情况下可立即被垃圾回收器释放。

之后,我们创建另一个 StringBuilder 对象赋值给 ref2,再将引用复制给 ref3。虽然 ref2 之后便不再使用,但是由于 ref3 保持着同一个 StringBuilder 对象的引用,因此在 ref3 使用完毕之前它不会被垃圾回收器回收。

复制代码
using System;
using System.Text;
class Test
{
static void Main()
{
StringBuilder ref1 = new StringBuilder ("object1");
Console.WriteLine (ref1);
// The StringBuilder referenced by ref1 is now eligible for GC.
StringBuilder ref2 = new StringBuilder ("object2");
StringBuilder ref3 = ref2;
// The StringBuilder referenced by ref2 is NOT yet eligible for GC.
Console.WriteLine (ref3); // object2
}
}

值类型的实例(和对象的引用)就存储在变量声明的地方。如果声明为类的字段或数组的元素,则该实例会存储在堆上。

C#中无法像 C++ 那样显式删除对象。未引用的对象最终将被垃圾回收器回收。

静态字段也会存储在堆上。与分配在堆上的对象(可以被垃圾回收)不同,这些变量一直存活直至应用程序域结束。

C# 7.0核心技术指南(37):C#语言基础 2.8.1

购书地址 https://item.jd.com/12681788.html?dist=jd

评论

发布