C#栈和堆的区别
C#栈和堆的区别
C#栈和堆的区别使用.Net框架开发程序的时候,我们无需关心内存分配问题,因为有GC这个大管家给我们料理一切。理解堆与栈对于理解.NET中的内存管理、垃圾回收、错误和异常、调试与日志有很大的帮助。垃圾回收的机制使程序员从复杂的内存管理中解脱出来,虽然绝大多数的C#程序并不需要程序员手动管理内存,但这并不代表程序员就无需了解分配的对象是如何被回收的,在一些特殊的场合仍需要程序员手动进行内存管理。
C#程序在CLR上运行的时候,内存从逻辑上划分两大块:栈,堆,由这两块组成我们C#程序的运行环境。
一、堆(heap)
堆是从下往上分配,所以已用的空间在自由空间下面,C#中所有引用类型的对象分配在托管堆上,托管堆在内存上是连续分配的,并且内存对象的释放受垃圾收集机制的管理,效率相对于栈来说要低的多。
二、栈(stack)
1、栈是自上向下进行填充,即由高内存地址指向低内存地址,并且内存分配是连续的,C#中所有的值类型和引用类型的引用都分配在栈上,栈根据后进先出的原则,依次对分配和释放内存对象。
2、我们可以把栈想象成一个接着一个叠放在一起的盒子。当我们使用的时候,每次从最顶部取走一个盒子。栈也是如此,当一个方法(或类型)被调用完成的时候,就从栈顶取走(called a Frame,译注:调用帧),接着下一个。堆则不然,像是一个仓库,储存着我们使用的各种对象等信息,跟栈不同的是他们被调用完毕不会立即被清理掉。
3、栈内存无需我们管理,也不受GC管理。当栈顶元素使用完毕,立马释放。而堆则需要GC(Garbage collection:垃圾收集器)清理。
三、对象内存的分配与销毁
当一个类的实例对象创建的时候,这个对象的不同成员按类别被分配到了不同的内存区域,值类型和引用类型的指针被分配到了栈上,引用类型的实例对象被分配到了托管堆上,静态成员被分配到了全局数据区。此时栈上的指针会指向堆上的对象。当对象使用完以后,引用和实际对象的联系就会断开,从而从而使对象冬眠。因为栈具有自我维护性,它的内存管理可以通过操作系统来完成,而此时堆上的冬眠对象就需要通过垃圾回收器(GC)使用一定的算法来进行回收,释放对象所占据的内存。
四、C#中的深拷贝与浅拷贝
1、深拷贝
又称深度克隆,它完全是新对象的产生,不仅复制所有的非静态值类型成员,而且复制所有引用类型成员的实际对象。(即栈上和堆上的成员均进行复制)
2、浅拷贝
又称影子克隆,只复制原始对象中的所有的非静态的值类型成员和所有引用类型成员的引用,就是说,原始对象和新对象共享所有引用类型成员的对象实例。(即只复制栈上的成员)
3、备注
不管是深拷贝还是浅拷贝,都不会复制全局数据区的成员,因为全局数据区的成员是静态成员,它属于某一个类,并不属于类的实例对象,因此无法复制。
C#中的深拷贝可以通过实现ICloneable接口来实现,但是在不是必须实现ICloneable接口的情况下,应避免类型继承ICloneable接口。因为这样做将强制所有的子类必须实现ICloneable接口,否则子类的新成员将不能被类型的深拷贝所覆盖。
- C# Task实现多线程
- c# Invoke和BeginInvoke 区别
- C#泛型List的用法
- C# Directory类的操作
- C# 正则表达式
- C#中equals和==的区别有哪些
- C#排序算法的比较
- C#中Dispose、析构函数、close的区别
- C#中TryParse的用法
- c#中使用stopwatch统计代码执行时间
- C#中Serializable序列化
- C#中字符串转换成日期
- C# 扩展方法
- C#中Obsolete
- SQL SERVER数据类型对应C#的数据类型
- C#如何读取Excel
- 不走心的古装造型 舒畅 毁容式 出演,萧蔷雷出新高度(不走心的古装造型)
- 嘉南传 第22集(嘉南传第22集)
- 哪版孙悟空最萌 黄渤躺萌了(哪版孙悟空最萌)
- 融入小人物的喜怒哀乐,黄渤饰演的角色为什么让人观看时欲罢不能(融入小人物的喜怒哀乐)
- 《极限挑战》深访都市夜归人,夜间打工者体验,黄磊录完憔悴了(极限挑战深访都市夜归人)
- Google 推出了一个游戏生成器,让不会编程的你也能自己设计游戏(推出了一个游戏生成器)
热门推荐
- 阿里云申请ssl证书要好久(阿里云部署SSL证书详解)
- web前端css总结(前端面试必备之CSS3的新特性)
- sql server go语句
- SQLServer中JSON文档型数据的查询问题解决(SQLServer中JSON文档型数据的查询问题解决)
- docker和jenkins自动化(Docker使用Git实现Jenkins发布、测试项目的详细流程)
- dedecms分页效果(dedecms重新定义cn_substr函数截取字数更准确)
- MySQL 使用事件(Events)完成计划任务(MySQL 使用事件Events完成计划任务)
- python数据类型基本知识入门(Python Pexpect库的简单使用方法)
- laravel算法(laravel批量生成假数据的方法)
- 虚拟主机哪里有免备案(免备案云主机的真假鉴别)