转载原地址  http://www.cnblogs.com/wangshenhe/archive/2013/02/18/2916275.html

[转]C#堆和栈的区别

理解堆与栈对于理解.NET中的内存管理、垃圾回收、错误和异常、调试与日志有很大的帮助。垃圾回收的机制使程序员从复杂的内存管理中解脱出来,虽然绝大多数的C#程序并不需要程序员手动管理内存,但这并不代表程序员就无需了解分配的对象是如何被回收的,在一些特殊的场合仍需要程序员手动进行内存管理。

在32位的处理器上,每个进程的虚拟内存为4GB,.NET会在这4GB的内存块中开辟出3块内存,分别作为栈、托管堆、和非托管堆

堆(heap):

堆是从下往上分配,所以已用的空间在自由空间下面,C#中所有引用类型的对象分配在托管堆上,托管堆在内存上是连续分配的,并且内存对象的释放受垃圾收集机制的管理,效率相对于栈来说要低的多。

栈(stack):

栈是自上向下进行填充,即由高内存地址指向低内存地址,并且内存分配是连续的,C#中所有的值类型和引用类型的引用都分配在栈上,栈根据后进先出的原则,依次对分配和释放内存对象。

对象内存的分配与销毁:

当一个类的实例对象创建的时候,这个对象的不同成员按类别被分配到了不同的内存区域,值类型和引用类型的指针被分配到了栈上,引用类型的实例对象被分配到了托管堆上,静态成员被分配到了全局数据区。此时栈上的指针会指向堆上的对象。当对象使用完以后,引用和实际对象的联系就会断开,从而从而使对象冬眠。因为栈具有自我维护性,它的内存管理可以通过操作系统来完成,而此时堆上的冬眠对象就需要通过垃圾回收器(GC)使用一定的算法来进行回收,释放对象所占据的内存。

C#中的深拷贝与浅拷贝

深拷贝:又称深度克隆,它完全是新对象的产生,不仅复制所有的非静态值类型成员,而且复制所有引用类型成员的实际对象。(即栈上和堆上的成员均进行复制

浅拷贝:又称影子克隆,只复制原始对象中的所有的非静态的值类型成员和所有引用类型成员的引用,就是说,原始对象和新对象共享所有引用类型成员的对象实例。(即只复制栈上的成员)

:不管是深拷贝还是浅拷贝,都不会复制全局数据区的成员,因为全局数据区的成员是静态成员,它属于某一个类,并不属于类的实例对象,因此无法复制。

C#中的深拷贝可以通过实现ICloneable接口来实现,但是在不是必须实现ICloneable接口的情况下,应避免类型继承ICloneable接口。因为这样做将强制所有的子类必须实现ICloneable接口,否则子类的新成员将不能被类型的深拷贝所覆盖。

最新文章

  1. npoi批量导入实现及相关技巧
  2. hiho一下 第六十六周
  3. easyui里弹窗的两种表现形式
  4. Android 自定义列表指示器
  5. 修饰符(static、final、abstract)第二篇
  6. POJ 2114 Boatherds【Tree,点分治】
  7. Java SAX Schema Validation
  8. CentOS Linux使用crontab运行定时任务详解
  9. 深度分析 Java 的枚举类型:枚举的线程安全性及序列化问题(转)
  10. C语言中的string.h中的内存字符串处理函数
  11. ComboBox值排序
  12. IO回忆录之怎样过目不忘(BIO/NIO/AIO/Netty)
  13. Javaweb---服务器Tomcat配置
  14. H5 marquee标签
  15. Math中的floor,round和ceil方法总结
  16. vis.js绘图库的一个BUG以及源码修正
  17. sql字段组合唯一
  18. DragonBones龙骨骨骼中的自定义事件(另有声音、动画事件)
  19. hystrix两种隔离模式分析
  20. 教你如何制作饼干icon教程

热门文章

  1. 1320. Graph Decomposition
  2. JAVA操作数据库插入中文表中显示乱码的解决方法
  3. UVa 11077 (循环分解 递推) Find the Permutations
  4. Oracle中使用escape关键字实现like匹配特殊字符,以及&字符的转义
  5. UVA 11294 Wedding(2-sat)
  6. Error: "DEVELOPER_DIR" is not defined at ./symbolicatecrash line 53
  7. 【C#学习笔记】List容器使用
  8. (转)HTTP协议详解
  9. 一次library cache pin故障的解决过程
  10. 一个响应式框架——agera