一、栈和堆是什么
程序运行时,它的数据必须存储在内存中。一个数据项需要多大的内存、存储在什么地方、以及如何存 储都依赖于该数据项的类型。
运行中的程序使用两个内存区域来存储数据:栈和堆。
1、栈 栈是一个内存数组,是一个LIFO(last-in first-out,后进先出)的数据结构。栈存储几种类型的数据: 某些类型变量的值、程序当前的执行环境、传递给方法的参数。
栈的特点:(1)数据只能从栈的顶端插入和删除。(2)把数据放到栈顶称为入栈。(3)从栈顶删除 数据称为出栈。
2、堆 堆是一块内存区域,在堆里可以分配大块的内存用于存储某种类型的数据对象。与栈不同,堆里的内存 能够以任意顺序存入和移除。下图展示了一个在堆里放了4项数据的程序。
二、值类型和引用类型
C# 中有两种类型:引用类型和值类型。
引用类型的变量存储对其数据(对象)的引用,而值类型的变量直接包含其数据。对于引用类型,两种 变量可引用同一对象;因此,对一个变量执行的操作会影响另一个变量所引用的对象。 对于值类型,每 个变量都具有其自己的数据副本,对一个变量执行的操作不会影响另一个变量(in、ref 和 out 参数变 量除外)。
三、总结
Heap space 堆空间: 所有存活的对象在此分配.
Stack space 栈空间: 方法调用时保存变量对象的引用或变量实例. 在C#中只要是成员变量,一旦它所在类被实例化后,都是作为一个整体放在堆内存的,不管它是值类型 还是引用类型。局部变量才是放在栈内存的。而类的方法是所有的对象共享的,方法是存在方法区的, 只用当调用的时候才会被压栈,不用的时候是占内存的。
因此关于值类型、引用类型各自在堆或栈上的内存分配可以总结为:
值类型作为方法中的局部变量时,在栈中分配,而作为类的成员变量时,在堆中分配;引用类型变量在 栈中分配,引用类型的实例在堆中分配