C# 中堆与栈的浅记

C# 中堆与栈的浅记

什么是堆和栈?

简言之,堆和栈是驻留在内存中的区域,它们的作用是帮助我们执行代码。在.Net Framework 环境下,当我们的代码执行时,内存中的堆和栈便存储了这些代码,并包含了代码执行所需要的全部信息。

这样说来还是有些抽象,那么,在堆和栈中究竟都保存了些什么呢?概括说来就是四类数据:

1、值类型数据

2、引用类型数据

3、指针

4、指令

下面对上述四类数据做以简单介绍。我们知道,C#中的数据类型分为两种,分别是值类型和引用类型。值类型数据直接在内存中的一个位置存储它们自身的内容(值);引用类型数据在内存中的一个位置存储指向内存中其它某个位置的地址,而在这个地址所指的位置中存储内容(值)。

对于指针,我们在.Net Framework环境中不会显示的使用指针,它们由CLR来管理。指针本身就是一个内存地址,它指向另一个内存位置。它的值就是一个内存地址或者为空(null)。

指令指的就是执行该方法的指令,当方法执行时需要在栈上为之分配空间。

那么,上述四类数据在堆与栈中是如何分配存储的?或者我们还可以把关心的范围再缩小一下,值类型数据与引用类型数据,它们是如何分配的?

规则:

1、引用类型数据总是存放在堆中;

2、值类型数据如果在方法体中被声明,那么它将存放在栈上;如果它作为引用类型的成员被声明,那么它将存放在堆中。

结合上面的两条规则,让我们分别来看一下堆与栈的不同之处。

在内存中,栈负责保存代码执行的路径(调用路径)。当我们的代码开始调用一个方法时,首先将放置一段编码指令到栈上,接下来再放置方法的参数,然后当代码执行到方法体中声明变量的位置,这些变量将被进栈至栈顶(注意,这里指的是值类型数据,第一种情况)。截止到这里,在方法体中被声明的值类型数据,它们被存放在了栈上。当方法执行完成,方法的结果被返回,此时所有在栈上的该方法所使用的内存空间都被清空,程序将自动回到栈上最初方法调用的位置。这也告诉了我们一点,栈是自行维护的,内存自动维护栈,不存在垃圾回收问题。

第二种情况,当代码执行到在方法体中被声明的引用类型数据的位置,引用类型数据将在堆上被创建,与此同时在栈上生成一个指向这个堆的指针,这个指针就存放在栈上。当方法执行结束后,栈上的相关信息被清除,但是,此时将剩下孤独的引用类型数据参数在堆中,这就是垃圾回收产生的原因。注意,垃圾回收是非常耗费性能的,这就是为什么我们要特别注意栈和堆的使用的原因。

以上内容是自己对于C#之中堆与栈的一个基本而又浅显的理解,后续还会继续深入思考,继续挖掘堆与栈的内容。

C# 中堆与栈的浅记

时间: 2024-11-07 15:13:39

C# 中堆与栈的浅记的相关文章

浅谈C#中堆和栈的区别(附上图解)

线程堆栈:简称栈 Stack 托管堆: 简称堆 Heap 使用.Net框架开发程序的时候,我们无需关心内存分配问题,因为有GC这个大管家给我们料理一切.如果我们写出如下两段代码: 代码段1: public int AddFive(int pValue) { int result; result = pValue + 5; return result; } 代码段2: public class MyInt { public int MyValue; } public MyInt AddFive(i

C/C++中堆与栈

本文介绍C/C++中堆,栈及静态数据区. 五大内存分区 在C++中,内存分成5个区,他们分别是堆.栈.自由存储区.全局/静态存储区和常量存储区.下面分别来介绍: 栈,就是那些由编译器在需要的时候分配,在不需要的时候自动清除的变量的存储区.里面的变量通常是局部变量.函数参数等. 堆,就是那些由new分配的内存块,他们的释放编译器不去管,由我们的应用程序去控制,一般一个new就要对应一个delete.如果程序员没有释放掉,那么在程序结束后,操作系统会自动回收. 自由存储区,就是那些由malloc等分

关于内存中堆和栈的知识和应用的总结

以前做的一个小项目最近经常不稳定,查了下日志大部分都是因为缓冲溢出而导致程序报错,于是乎在网上查找了一些关于内存使用的内容,收获颇丰.在此将前人的一些精华总结收录于此,加深印象.有不对或不足的地方请大家予以指正. 文章链接:http://blog.csdn.net/szchtx/article/details/7981401 http://www.cppblog.com/oosky/archive/2006/01/21/2958.html http://www.cnblogs.com/lln77

C语言中堆、栈、队列

C语言中堆.栈和队列: 1.堆和栈 (1)数据结构的堆和栈 堆栈是两种数据结构. 栈(栈像装数据的桶或箱子):是一种具有后进先出性质的数据结构,也就是说后存放的先取,先存放的后取.这就如同要取出放在箱子里面底下的东西(放入的比较早的物体),首先要移开压在它上面的物体(放入的比较晚的物体). 堆(堆像一棵倒过来的树):是一种经过排序的树形数据结构,每个结点都有一个值.通常所说的堆的数据结构,是指二叉堆.堆的特点是根结点的值最小(或最大),且根结点的两个子树也是一个堆.由于堆的这个特性,常用来实现优

Java中堆、栈、方法区的联系

引言:Java中堆.栈.方法区的联系,为了更好的理解三者间的关系,本文用Test类的 声明->调用 来简单的展示这一过程. Test类: 一.编译时 在编译时会将对象Test . 常量和静态方法存入方法区 方法区分为2块: 1.对象区(加载时会将静态成员直接加载进去) 2.常量区 二.实例化时 在对象实例化时,会在堆中为对象分配一块空间. 三.调用对象的方法时 次出有2种情况: 1.静态方法调用 会直接去方法区找到add()方法进栈使用,使用完弹栈. 2.非静态方法调用 原文地址:https:/

C++中堆和栈的完全解析

内存分配方面: 堆: 操作系统有一个记录空闲内存地址的链表,当系统收到程序的申请时,会遍历该链表,寻找第一个空间大于所申请空间的堆结点,然后将该结点从空闲结点链表中删 除,并将该结点的空间分配给程序,另外,对于大多数系统,会在这块内存空间中的首地址处记录本次分配的大小,这样代码 中的delete语句才能正确的释放本内存空间.我们常说的内存泄露,最常见的就是堆泄露(还有资源泄露),它是指程序在运行中出现泄露,如果程序被关闭掉的话,操作系统会帮助释放泄露的内存. 栈:在函数调用时第一个进栈的主函数中

计算机中 堆 、栈、队列 介绍

1. 堆分配和栈分配的差别 一般认为在 c 中分为这几个存储区 栈堆全局区:   1 栈 有编译器自动分配释放 2 堆 一般由程序员分配释放,若程序员不释放,程序结束时可能由 OS 回收 3 全局区(静态区),全局变量和静态变量的存储是放在一块的,初始化的全局变量和静态变量在一块区域,未初始化的全局变量和 未初始化的静态变量在相邻的另一块区域. 程序结束释放 4 另外还有一个专门放常量的地方. 程序结束释放 区别:   在函数体中定义的变量通常是在栈上,用 malloc, calloc, rea

C语言中堆和栈的区别

原文:http://blog.csdn.net/tigerjibo/article/details/7423728 一.前言: C语言程序经过编译连接后形成编译.连接后形成的二进制映像文件由栈,堆,数据段(由三部分部分组成:只读数据段,已经初始化读写数据段,未初始化数据段即BBS)和代码段组成,如下图所示: 1.栈区(stack):由编译器自动分配释放,存放函数的参数值,局部变量等值.其操作方式类似于数据结构中的栈. 2.堆区(heap):一般由程序员分配释放,若程序员不释放,则可能会引起内存泄

java中堆与栈的区别

堆与栈都是java中常用的存储结构,是内存中存放数据的地方. 堆:主要存放引用类型的变量,以及运行时创建(new)的对象.主要用于储存对象,存取速度慢,可以运行时动态分配内存,生命周期不需要提前确定. 栈:主要存放基础类型的变量,以及对象的引用变量.主要用于执行程序,存取速度快,生命周期必须要提前确定,缺少灵活性. public class Test{ public static void main(String[] args){ int i=0; //基本数据类型变量 鸭子 duck =new