欢迎来到天天文库
浏览记录
ID:13900739
大小:37.50 KB
页数:4页
时间:2018-07-24
《c#基础知识梳理系列十一:垃圾回收机制》由会员上传分享,免费在线阅读,更多相关内容在行业资料-天天文库。
1、摘要基于.NET平台的开发语言中,最让开发人员爽的一点就是垃圾回收处理机制,在编码过程中,终于可以解放你的双手来关注更重要的事情。很多的资料中在讲到.NET中的垃圾回收机制时都说“CLR在合适的时候进行垃圾回收”,但什么时候才是“合适的时候”?内存又是如何分配的?CLR是如何对内存进行回收的?这一章我们来讨论有关垃圾回收的相关内容。第一节垃圾回收机制早期的C/C++开发中,一个对象的生命周期大概像这样:计算对象大小——查找可用内存——初始化对象——使用对象——摧毁对象。如果在上面的过程中,开发人员忘记了“摧毁对象”这一步骤,则很有可能导致内存泄露!这是一个非
2、常可怕的事情!幸好,CLR的开发人员为我们解决了这一问题,在.NETFramework中引入了垃圾回收机制,使得开发人员不需要再过多地关注内存释放的问题,CLR会在合适的时候进行执行垃圾回收来释放不再使用的内存。这里就像一个邪恶的男人所说的话:给我一个女人,我能创造一个民族!其实一个新世界你都可以去创造,前提是要有一个足够大的星球内存来容纳你的子孙!CLR就是这么认为的。在激活一个进程时,CLR会先保留一块连续的内存,在主线程启动过程中,可能会初始化一系列对象,CLR先计算对象大小及其开销所占用的字节数,接着会在连续的内存块中为这些对象分配内存,这些对象被配
3、置在第0代内存,在构造第0代内存的时候会分配一个默认大小的内存,随着程序的运行,可能会初始化更多的对象,CLR发现第0代内存不能装载更多的新生对象,此时CLR会启动垃圾回收器对第0代内存进行回收,不再使用的对象所占用的内存会被释放,接着把0代对象提升为第1代,然后把新生对象配置在第0代内存区中。http://yinxiang.wan128.cnCLR使用了3个阶段的代,每次新分配的对象都会被配置在第0代内存中,最老的对象在第2代内存中,每次为新对象分配内存时,都可能会进行垃圾回收以释放内存,很显然CLR认为“内存永远也使用不完”,很显然CLR为我们自动管理了
4、内存垃圾,很显然CLR的这个“认为”在我们开发人员看来是不成立的,我们从以下几个方面来解读垃圾回收机制。 第二节内存分配垃圾回收是对引用类型而言的。CLR要求引用类型的对象从托管堆中分配内存的,值类型是从栈中分配内存。在C#中通常使用new操作符来创建一个对象,编译器将会在IL中生成newobj指令,执行一个newobj指令会有以下过程:(在前一节中我们已经知道,在一个进程启动时会先保留一个连续的内存块)先计算类型及其基类型的字段所需要的字节数A,再计算类型对象的指针和一个同步索引块共8或16个字节,到此总共需要(A+8或18)字节的内存,CLR会检查当前进
5、程区是否有足够的内存来容纳(A+8或16)个字节的对象,如果有,则将新对象放其中,否则CLR进行垃圾回收,释放不再使用的内存来容纳新的对象,在整个进程的生命周期中,CLR会维护一个指针P,它一直指向当前进程所分配的最后一个对象内存的结尾处而不会跑出当前进程内存区边界每次计算新的将要创建的对象所需要的字节数时,CLR都是通过P加上新的需要的字节数进行检查可用内存区,如果超出了地址末尾,则表示当前的托管堆已经被用完,准备进行垃圾回收了。由于进程拥有一个独立连续的内存区,所以CLR能保证创建的新对象基本上都是紧挨着放置的。 第三节代当托管堆的内存被用完,新生的对象
6、无处放置时,CLR就要开始进行垃圾回收了,随着程序的持续运行,托管堆可能越来越大,如果要对整个托管堆进行垃圾回收(下面会讲到如何回收),势必会严重影响性能,因为有时可能仅仅需要数十个字节就能容纳新的对象,有时候可能要对可达的对象进行搬迁,为了小范围有目的性地进行垃圾回收,CLR使用了“代”概念来优化垃圾回收器,代是垃圾回收机制使用的一个逻辑技术,也是一种算法,它把托管堆中的内存分为3个代(截止到目前.NETFramework4.0有3个代:0、1、2)。进程在初始化时,CLR为托管堆初始化为包含0个对象的一块内存区域,新添加到堆中的对象为第0代对象,CLR在
7、初始化第0代内存区时会分配一个默认的配额,假设为512K,不同的.NET框架和版本,可能这个配额不相同。假设进程及其线程初始化完成后分配了4个对象这4个对象占据了512K的内存,程序继续运行,当再分配第5个对象Obj5的时候,发现第0代已无可用内存,此时CLR会启动垃圾回收器进行垃圾回收,假如上面的Obj3已经无效,此是Obj3的内存会被释放出来,接着搬迁Obj4对象到Obj3的位置(在Obj2的内存地址末尾处),存活下来的对象Obj1、Obj2和Obj4会被提升为第1代对象,第1代的内存区域根据程序运行的情况,CLR可能会为其分配20M(也可能是其他值)大
8、小的内存区,第0代内存暂时为空,接着将Obj5分配到
此文档下载收益归作者所有