C# 堆与栈

前言:今天我们着重讲解.Net下的栈(Stack)和托管堆(Heap)(简称堆)。如果你想提高程序性能,理解栈和堆,那学习这块更是必须的!

一、C#中的值类型和引用类型

在讲堆与栈之前,我们先看看值类型和引用类型,这样更能帮助我们理解堆与栈。

通过上面这个表格,我们可以看到,类型被分为两种:值类型(基本数据类型、枚举类型、结构类型)和引用类型(类、接口、数组)。

下来,我们进行简单理解:

  1. 值类型只需要一段单独的内存,用于存储实际的数据(单独定义的时候放在栈中)。
  2. 引用类型需要两段内存。
  1. 第一段存储实际的数据,它总是位于堆中。
  2. 第二段是一个引用,指向数据在堆中的存放位置。

1、值类型与引用类型的存储方式

  • 值类型:值类型总是分配在它声明的地方,做为局部变量时,存储在栈上;类对象的字段时,则跟随此类存储在堆中。
  • 引用类型:引用类型存储在堆中。类型实例化的时候,会在堆中开辟一部分空间存储类的实例。类对象的引用还是存储在栈中。

2、通过一个案例理解一下

// 值类型,保存在栈中 int num = 100; // 引用类型,保存在堆中 int[] nums = {1,2,3,4,5}; // 接下来,我们输出一下 Console.WriteLine(num); Console.WriteLine(nums);

通过上面这个例子,我们可以看到,num为值类型,所以它直接输出了值,而我们的nums为引用类型,它无法直接输出值,而是输出了一个引用。

3、值类型与引用类型的区别

  1. 值类型与引用类型都继承自Systerm.Object类。不同之处,几乎所有的引用类型都是直接从Systerm.Object继承,而值类型则是继承Systerm.Object的子类Systerm.ValueType类。

  2. 我们在给引用类型的变量赋值的时候,其实只是赋值了对象的引用;而给值类型变量赋值的时候是创建了一个副本(说通俗点,就是克隆了一个变量)。

二、堆与栈简单理解

C#程序在CLR上运行的时候,内存从逻辑上划分两大块:栈,堆。这俩基本元素组成我们C#程序的运行环境。

1、堆与栈概念介绍

:在c里面叫堆,在c#里面其实叫托管堆。

:就是堆栈,因为和堆一起叫着别扭,就简称为栈。

2、托管堆

托管堆不同于堆,它是由CLR(公共语言运行库(Common Language Runtime))管理,当堆中满了之后,会自动清理堆中的垃圾。所以,做为.net开发,我们不需要关心内存释放的问题。

3、内存堆栈与数据堆栈

内存堆栈:存在内存中的两个存储区(堆区,栈区)。

  1. 栈区:存放函数的参数、局部变量、返回数据等值,由编译器自动释放。
  2. 堆区:存放着引用类型的对象,由CLR释放。

数据堆栈:是一种后进先出的数据结构,它是一个概念,主要是栈区。

三、堆与栈区别分析

栈通常保存着我们代码执行的步骤,如一个值类型的变量的初始化或者一个方法的声明。而堆上存放的则多是对象,数据等。我们可以把栈想象成一个接着一个叠放在一起的盒子。当我们使用的时候,每次从最顶部取走一个盒子。同样,我们的栈也是如此,当一个方法(或类型)被调用完成的时候,就从栈顶取走,接着下一个,这也就是我们常说的 “先进后出” 。堆则不然,像是一个仓库,储存着我们使用的各种对象等信息,当我们需要调用的时候,会去里面自行寻找并调用。跟栈不同的是它们被调用完毕不会立即被清理掉。

注意:栈内存无需我们管理,也不受GC管理。当栈顶元素使用完毕,立马释放。而堆则需要GC(Garbage Collection:垃圾收集器)清理。

四、堆与栈存储讲解

我们把内存分为堆空间和栈空间,区别如下:

  1. 栈空间比较小,但是读取速度快。
  2. 堆空间比较大,但是读取速度慢。

1、栈的深入讲解

栈(Stack)最明显的特征就是“先进后出”,本质上讲堆栈也是一种线性结构,符合线性结构的基本特点:即每个节点有且只有一个前驱节点和一个后续节点。栈把所有操作限制在"只能在线性结构的某一端"进行,而不能在中间插入或删除元素。我们把数据放入栈顶称为入栈(push), 从栈顶删除数据称为出栈(pop)。

2、堆的深入讲解

堆(Heap)是一块内存区域,与栈不同,堆里的内存能够以任意顺序存入和移除。

五、GC(Garbage Collection)垃圾收集器介绍

CLR的GC就是内存管理机制,我们写程序不需要关心内存的使用,因为这些都是CLR帮我们做了。

本文转载自:https://blog.csdn.net/qq_44034384/article/details/106611384

鲸之声为您拼命加载中...