堆和栈是两种可以分配的内存。
栈保存代码的运行路径。堆保存对象。
栈好比整齐摆放的盒子。堆则好比杂乱无章的盒子。
在堆中我们可以轻易找到需要的对象,而由于默认访问最顶端的栈,当栈中的方法执行完毕之后就会丢弃,然后继续查找最顶端的盒子,直到发现合适的。
借用其他博主的图片。左边是栈,右边是堆。
栈是内存自主维护的。而堆则需要垃圾回收机制
堆和栈主要存放了四种类型的数据:值类型,引用类型,指针和指令。
值类型和引用类型
指针:
由公共语言运行时(CLR)来管理。自身占用内存,指向对象的内存地址。它的值为空或者是内存地址。
引用类型总是放在堆上。
值类型和指针总是放在他们被声明的地方。
使用如下例子解释:
public void Method(int z){ int x=1; int y=2; A a=new A(); a.Result=z+2; }
方法与方法的参数放置在栈上。
x=1,y=2依次被放在栈上,就像砌房子一样,x=1在下,栈依据先进后出的规则。
a为引用对象,放置在堆上。
z为方法的参数,显然是在栈上。那么就会在栈上生成一个指向含有a的那个堆的指针。
在方法结束之后。栈上的变量和指针全部清空。也就是这里的x,y,z以及指向a的指针(指针也占内存)。
而在堆上的变量a并没有立即删除。需要等到垃圾回收机制来回收变量。
还有一个典型的例子:
A a1=new A(); a1.Result=3; A a2=a1; a2.Result=4;
此时a2.Result依然是3.因为将a1赋值给a2,实际是将a2指向a1的堆内存地址,值不会变。