C# 中堆与栈的浅记
C# 中堆与栈的浅记
什么是堆和栈?
简言之。堆和栈是驻留在内存中的区域,它们的作用是帮助我们运行代码。在.Net Framework 环境下,当我们的代码运行时,内存中的堆和栈便存储了这些代码,并包括了代码运行所须要的所有信息。
这样说来还是有些抽象。那么,在堆和栈中到底都保存了些什么呢?概括说来就是四类数据:
1、值类型数据
2、引用类型数据
3、指针
4、指令
以下对上述四类数据做以简介。我们知道,C#中的数据类型分为两种。各自是值类型和引用类型。
值类型数据直接在内存中的一个位置存储它们自身的内容(值)。引用类型数据在内存中的一个位置存储指向内存中其他某个位置的地址,而在这个地址所指的位置中存储内容(值)。
对于指针。我们在.Net Framework环境中不会显示的使用指针,它们由CLR来管理。指针本身就是一个内存地址,它指向还有一个内存位置。
它的值就是一个内存地址或者为空(null)。
指令指的就是运行该方法的指令,当方法运行时须要在栈上为之分配空间。
那么,上述四类数据在堆与栈中是怎样分配存储的?或者我们还能够把关心的范围再缩小一下,值类型数据与引用类型数据,它们是怎样分配的?
规则:
1、引用类型数据总是存放在堆中;
2、值类型数据假设在方法体中被声明。那么它将存放在栈上;假设它作为引用类型的成员被声明。那么它将存放在堆中。
结合上面的两条规则,让我们分别来看一下堆与栈的不同之处。
在内存中,栈负责保存代码运行的路径(调用路径)。当我们的代码開始调用一个方法时,首先将放置一段编码指令到栈上,接下来再放置方法的參数。然后当代码运行到方法体中声明变量的位置,这些变量将被进栈至栈顶(注意。这里指的是值类型数据。第一种情况)。截止到这里,在方法体中被声明的值类型数据。它们被存放在了栈上。当方法运行完毕,方法的结果被返回,此时全部在栈上的该方法所使用的内存空间都被清空,程序将自己主动回到栈上最初方法调用的位置。
这也告诉了我们一点。栈是自行维护的,内存自己主动维护栈,不存在垃圾回收问题。
另外一种情况,当代码运行到在方法体中被声明的引用类型数据的位置。引用类型数据将在堆上被创建。与此同一时候在栈上生成一个指向这个堆的指针,这个指针就存放在栈上。当方法运行结束后。栈上的相关信息被清除,可是,此时将剩下孤独的引用类型数据參数在堆中。这就是垃圾回收产生的原因。
注意,垃圾回收是很耗费性能的。这就是为什么我们要特别注意栈和堆的使用的原因。
以上内容是自己对于C#之中堆与栈的一个基本而又浅显的理解。兴许还会继续深入思考。继续挖掘堆与栈的内容。
C# 中堆与栈的浅记的更多相关文章
- 转载:C++中堆和栈的区别
C++中堆和栈的区别,自由存储区.全局/静态存储区和常量存储区 文章来自一个论坛里的回帖,哪个论坛记不得了! 在C++中,内存分成5个区,他们分别是堆.栈.自由存储区.全局/静态存储区和 ...
- C/C++中堆与栈
本文介绍C/C++中堆,栈及静态数据区. 五大内存分区 在C++中,内存分成5个区,他们分别是堆.栈.自由存储区.全局/静态存储区和常量存储区.下面分别来介绍: 栈,就是那些由编译器在需要的时候分 ...
- Java中堆和栈的区别(转)
栈与堆都是Java用来在Ram中存放数据的地方.与C++不同,Java自动管理栈和堆,程序员不能直接地设置栈或堆. Java的堆是一个运行时数据区,类的对象从中分配空间.这些对象通过new. ...
- C语言中堆和栈的区别
原文:http://blog.csdn.net/tigerjibo/article/details/7423728 C语言中堆和栈的区别 一.前言: C语言程序经过编译连接后形成编译.连接后形成的二进 ...
- 【转载】c++中堆、栈内存分配
一.内存划分 1.栈区(stack)— 由编译器自动分配释放 ,存放函数参数值,局部变量值等.其操作方式类似于数据结构中栈.2.堆区(heap) — 一般由程序员分配释放, 若程序员不释放,程序结束时 ...
- C++中堆和栈的完全解析
C++中堆和栈的完全解析 内存分配方面: 堆: 操作系统有一个记录空闲内存地址的链表,当系统收到程序的申请时,会遍历该链表,寻找第一个空间大于所申请空间的堆结点,然后将该结点从空闲结点链表中删 除,并 ...
- C中堆和栈的区别
C++中堆和栈的完全解析 内存分配方面: 堆: 操作系统有一个记录空闲内存地址的链表,当系统收到程序的申请时,会遍历该链表,寻找第一个空间大于所申请空间的堆结点,然后将该结点从空闲结点链表中删 除,并 ...
- Java 中堆和栈有什么区别?
JVM 中堆和栈属于不同的内存区域,使用目的也不同.栈常用于保存方法帧和局 部变量,而对象总是在堆上分配.栈通常都比堆小,也不会在多个线程之间共享, 而堆被整个 JVM 的所有线程共享.
- c++中堆、栈内存分配
转自:https://blog.csdn.net/qingtingchen1987/article/details/7698415 一个由C/C++编译程序占用内存分为以下几个部分1.栈区(stack ...
随机推荐
- element-ui 组件源码分析整理笔记目录
element-ui button组件 radio组件源码分析整理笔记(一) element-ui switch组件源码分析整理笔记(二) element-ui inputNumber.Card .B ...
- 从零开始学习html(六)开始学习CSS,为网页添加样式
一.认识CSS样式 <!DOCTYPE HTML> <html> <head> <meta http-equiv="Content-Type&quo ...
- onkeypress 在js函数返回false后没有反应
一.解决方案: 把 onkeypress = "function()" 改为 onkeypress = "event.returnValue=function()&quo ...
- 机器学习是万能的吗?AI落地有哪些先决条件?
机器学习是万能的吗?AI落地有哪些先决条件? https://mp.weixin.qq.com/s/9rNY2YA3BMpoY8NQ_rVIjQ 1.引言 入门机器学习或从事其相关工作前,不知道你思考 ...
- Salesforce小知识:累计汇总字段类型
累计汇总字段类型的定义 Salesforce中可以在两个对象之间建立关系.一个对象的某一条记录可以有若干条相关联的其他对象记录. 累计汇总字段可以将这些相关联的记录中的某些字段值汇总起来,显示给用户. ...
- Java数据解析---SAX
一.Sax解析 是从头到尾逐行逐个元素读取内容,修改较为不便,但适用于只读的大文档. Sax采用事件驱动的方式解析文档.简单点说,如同在电影院看电影一样,从头到尾看一遍就完了,不能回退(Dom可来来回 ...
- SQLite保存报错sqlite.SQLiteConstraintException: UNIQUE constraint failed: ······ code 1555
往数据库里保存数据的时候报错,用的afinal框架,明明在save操作之前执行了一遍deleteAll操作,还是报错. 百度了一下说报这种错有两种情况:一是定义的字段为not null ,插入时对应的 ...
- onSaveInstanceState场景
需要注意的是, onSaveInstanceState()方法并不是一定会被调用的, 因为有些场景是不需要保存状态数据的. 比如用户按下BACK键退出activity时, 用户显然想要关闭这个acti ...
- 【Java入门提高篇】Day29 Java容器类详解(十一)LinkedHashSet详解
当当当当当当当,本来打算出去浪来着,想想还是把这个先一起写完吧,毕竟这篇的主角跟我一样是一个超级偷懒的角色——LinkedHashSet,有多偷懒?看完你就知道了. 本篇将从以下几个方面对Linked ...
- Python:GUI之tkinter学习笔记3事件绑定
相关内容: command bind protocol 首发时间:2018-03-04 19:26 command: command是控件中的一个参数,如果使得command=函数,那么点击控件的时候 ...