内存栈与堆的区别C#
C# 堆与栈
理解堆与栈对于理解.NET中的内存管理、垃圾回收、错误和异常、调试与日志有很大的帮助。垃圾回收的机制使程序员从复杂的内存管理中解脱出来,虽然绝大多数的C#程序并不需要程序员手动管理内存,但这并不代表程序员就无需了解分配的对象是如何被回收的,在一些特殊的场合仍需要程序员手动进行内存管理。
在32位的处理器上,每个进程的虚拟内存为4GB,.NET会在这4GB的内存块中开辟出3块内存,分别作为栈、托管堆、和非托管堆
堆(heap):
堆是从下往上分配,所以已用的空间在自由空间下面,C#中所有引用类型的对象分配在托管堆上,托管堆在内存上是连续分配的,并且内存对象的释放受垃圾收集机制的管理,效率相对于栈来说要低的多。
栈(stack):
栈是自上向下进行填充,即由高内存地址指向低内存地址,并且内存分配是连续的,C#中所有的值类型和引用类型的引用都分配在栈上,栈根据后进先出的原则,依次对分配和释放内存对象。
对象内存的分配与销毁:
当一个类的实例对象创建的时候,这个对象的不同成员按类别被分配到了不同的内存区域,值类型和引用类型的指针被分配到了栈上,引用类型的实例对象被分配到了托管堆上,静态成员被分配到了全局数据区。此时栈上的指针会指向堆上的对象。当对象使用完以后,引用和实际对象的联系就会断开,从而从而使对象冬眠。因为栈具有自我维护性,它的内存管理可以通过操作系统来完成,而此时堆上的冬眠对象就需要通过垃圾回收器(GC)使用一定的算法来进行回收,释放对象所占据的内存。
C#中的深拷贝与浅拷贝
深拷贝:又称深度克隆,它完全是新对象的产生,不仅复制所有的非静态值类型成员,而且复制所有引用类型成员的实际对象。(即栈上和堆上的成员均进行复制)
浅拷贝:又称影子克隆,只复制原始对象中的所有的非静态的值类型成员和所有引用类型成员的引用,就是说,原始对象和新对象共享所有引用类型成员的对象实例。(即只复制栈上的成员)
注:不管是深拷贝还是浅拷贝,都不会复制全局数据区的成员,因为全局数据区的成员是静态成员,它属于某一个类,并不属于类的实例对象,因此无法复制。
C#中的深拷贝可以通过实现ICloneable接口来实现,但是在不是必须实现ICloneable接口的情况下,应避免类型继承ICloneable接口。因为这样做将强制所有的子类必须实现ICloneable接口,否则子类的新成员将不能被类型的深拷贝所覆盖。
内存栈与堆的区别C#的更多相关文章
- 面试题思考:Stack和Heap的区别 栈和堆的区别
堆栈的概念: 堆栈是两种数据结构.堆栈都是一种数据项按序排列的数据结构,只能在一端(称为栈顶(top))对数据项进行插入和删除.在单片机应用中,堆栈是个特殊的存储区,主要功能是暂时存放数据和地址,通常 ...
- C++ 栈和堆的区别
C++中的存储区分为全局数据区.代码区.堆.栈. 全局数据区存放静态数据.全局变量.常量. 代码区存放所有类成员函数和非成员函数的代码. 栈区存放用于函数的返回地址.形参.局部变量.返回类型. 堆区存 ...
- Java学习之栈和堆的区别
在函数中定义的一些基本类型的变量和对象的引用变量都在函数的栈内存中分配. 当在一段代码块定义一个变量时,Java就在栈中为这个变量分配内存空间,当超过变量的作用域后,Java会自动释放掉为该变量所分配 ...
- js栈和堆的区别
一. 堆(heap)和栈(stack) 栈(stack)会自动分配内存空间,会自动释放.堆(heap)动态分配的内存,大小不定也不会自动释放. 二. 基本类型和引用类型 基本类型:简单的数据段,存 ...
- Java栈和堆的区别
一.栈空间 1.栈空间存储数据效率高 2.栈中的数据是按“先进后出”的方式管理 3.栈空间存储空间比较小,不能存放大量的数据 4.JVM将基本类型的数据存放在栈空间 帮助理解 1.“客栈” 能提供很多 ...
- 栈 堆 stack heap 堆内存 栈内存 内存分配中的堆和栈 掌握堆内存的权柄就是返回的指针 栈是面向线程的而堆是面向进程的。 new/delete and malloc/ free 指针与内存模型
小结: 1.栈内存 为什么快? Due to this nature, the process of storing and retrieving data from the stack is ver ...
- Java的栈和堆
JVM的内存区域可以被分为:线程栈,堆,静态方法区(实际上还有更多功能的区域,并且这里说的是JVM的内存区域) 线程栈: 注意这个栈和数据结构中的stack有相似之处,但并不是用户态的.准确 ...
- JVM内存结构之堆、栈、方法区以及直接内存、堆和栈区别
JVM内存结构之堆.栈.方法区以及直接内存.堆和栈区别 一. 理解JVM中堆与栈以及方法区 堆(heap):FIFO(队列优先,先进先出):二级缓存:*JVM中只有一个堆区被所有线程所共享:对象和数 ...
- iOS开发中的内存分配(堆和栈)
进程的内存分区 所有进程(执行的程序)都必须占用一定数量的内存,它或是用来存放从磁盘载入的程序代码,或是存放取自用户输入的数据等等.不过进程对这些内存的管理方式因内存用途不一而不尽相同,有些内存是事先 ...
随机推荐
- requests库入门07-patch请求
使用data参数提交 设置邮件能见度,这个接口用来设置邮件是公共可见,还是私有的 import requests test_url = 'https://api.github.com' def get ...
- Threading.local
在多线程环境下,每个线程都有自己的数据.一个线程使用自己的局部变量比使用全局变量好,因为局部变量只有线程自己能看见,不会影响其他线程,而全局变量的修改必须加锁. Threading.local可以创建 ...
- 微信小程序弹出层点击穿透问题
问题描述:使用小程序的modal组件实现遮罩层效果时,会出现滚动穿透的问题,即遮罩层后面的页面依旧可以滚动. 解决方案: 给底层页面动态添加 position:fixed; 代码: wxml: < ...
- 简单的三级联动demo
<!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <title&g ...
- MySQL数据库的各种存储引擎详解
原文来自:MySQL数据库的各种存储引擎详解 MySQL有多种存储引擎,每种存储引擎有各自的优缺点,大家可以择优选择使用: MyISAM.InnoDB.MERGE.MEMORY(HEAP).BDB ...
- MQ选型之RabbitMQ
RabbitMQ是部署最广泛的开源消息代理.[官方原话] 前言: MQ 是什么?队列是什么,MQ 我们可以理解为消息队列(message queue),队列我们可以理解为管道.以管道的方式做消息传递. ...
- Codeforces 1045G AI robots [CDQ分治]
洛谷 Codeforces 简单的CDQ分治题. 由于对话要求互相看见,无法简单地用树套树切掉,考虑CDQ分治. 按视野从大到小排序,这样只要右边能看见左边就可以保证互相看见. 发现\(K\)固定,那 ...
- linux软件安装、rpm操作命令、本地yum配置(有什么用)
1.yum是什么? yum的全称是yellow dog updater,modified,是一个shell前端软件包管理器;基于RPM包管理,能够从指定的服务器下载RPM包并自动安装,可以自动处理依赖 ...
- C#将DLL嵌入到exe当中
1.选中项目文件,找到Resources.resx,双击Resources.resx,然后添加文件(选择需要的dll文件),点击确定,项目下会自动生成一个Resources文件夹,里面包含添加dll. ...
- Confluence 6 你模板中可用的对象
包含宏正文和参数,下面的 Confluence 对象在宏中可用: $body 宏的正文(如果宏有正文的话) String $paramfoo, $parambar, ...$param<name ...