码迷,mamicode.com
首页 > 其他好文 > 详细

垃圾回收

时间:2017-09-16 13:42:44      阅读:122      评论:0      收藏:0      [点我收藏+]

标签:静态   相对   images   维护   .com   全局   其他   大于   遇到   

CLR管理的内存块

  • 线程的堆栈
  • GC堆
  • LOH(large Object Heap)堆对象大于85000字节

托管堆=GC Heap + Loader Heap

什么样的对象会被回收

GC只回收GC堆中的对象,堆栈的不管
只有当前不可达的对象会被回收

先介绍下应用程序根这个概念,应用程序根可以是:

  • 本地变量或者全局变量(C#不支持全局变量,但CIL允许)
  • 类型的静态成员或者静态属性
  • 传递到方法中的参数变量
  • CPU寄存器所引用的对象

技术分享

如图中在运行RunTest时, _itemitem都是应用程序根,但如果RunTest执行完,item则被栈销毁,Phone对象少了一个能引用他的根

但Phone不会被销毁,因为静态变量_item始终引用着它。
相反,图中对象3与对象4,没有根引用它们,就当前运行环境而言无法获取它们,所以它们就是下一次垃圾回收的对象

怎么回收

就算法而言,GC采用的是mark-and-compact(标记和压缩)
先假设所有对象是可回收,再根据找到可达对象,把他添加到可达对象图(如果可达对象引用了其他对象,那“其他对象”也是可达的),最后将不可达的对象清空,留下的对象重新排布,压缩内存.
技术分享
在压缩内存时,GC会重新找到一个新的较大的连续空间,将对象复制过来,并修改所有引用

显然这种操作是耗性能的,有时候就是会遇到生命周期比较长的对象,如果频繁地对它垃圾回收,势必会产生很多压缩内存的消耗。

于是GC结合的机制提升垃圾回收性能
这种机制的对你的代码做出以下几点假设

  • 对象越新,生命周期越短
  • 对象越老,生命周期越长
  • 回收堆的一小部分,速度快与回收整个堆

该机制将对象分成三代,分别是0,1,2代。每一代的大小依次增大,0代最小,2代最大。
代的大小在运行时也可能会调整,并不是固定的。
新的对象都视为0代,垃圾回收时存活下来的0代会被提升到1代,当0代与1代空间都不足时,1代的对象才会提升到2代(同时0代提升到1代)

技术分享

什么时候回收

  • 调用GC.Colect
  • 内存不足(0代满了)
  • CLR卸载AppDomain
  • CLR关闭

大对象

对象大于85000字节时会保存到LOH(large Object Heap)堆

  • 没有代级的概念,所有对象都被视为第2代。
  • 不进行对象移动和空间压缩,因为移动大对象是相对耗时的操作。因此,需要一个链
    表来维护空闲区域的位置。
  • 对象不会被分配在末尾,而会在链表中寻找合适的位置,因此会存在碎片的问题

资料

  • 《CLR via in C#》
  • 《.Net之美》
  • 《你必须知道的.Net》

垃圾回收

标签:静态   相对   images   维护   .com   全局   其他   大于   遇到   

原文地址:http://www.cnblogs.com/Recoding/p/7530787.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!