zoukankan      html  css  js  c++  java
  • 对.NET垃圾回收机制的初略理解

      程序员首先是人,不是所有人都是细心的,更何况细心的人也会有粗心的时候,因此经常会出现忘了释放已经使用完的资源,导致资源紧张。有时候是不愿去做这些扫尾的事情,因为觉得他的时间应该是用在更伟大更崇高的事业上面,至于清理垃圾这些鸡毛蒜皮的事实在不值得他一屑。于是就有了垃圾回收机制,既减轻了程序员的负担,也避免了资源的泄漏,一举两得。

    首先了解一下对象的整个生命过程: 

     1.给对象分配内存;

     2.调用对象构造器进行初始化;

     3.使用资源通过访问对象成员;

     4.销毁对象;主要是通过Finalization,Dispose和Close方法

     5.释放内存。

      垃圾回收会在第1步和第5步发生。在第5步进行垃圾回收比较好理解,第1步是如何触发垃圾回收的呢?第1步包含三个过程:首先根据类型成员所需空间总合,然后加上两个额外开销:类型指针(type object pointer)和同步模块索引(sync block index),32位系统下一般是8bytes,64位则是16bytes,最后就是判断当前托管堆中是否有足够的空间去分配这个对象。当满足时就为对象分配所需要的内存,如果不满足就会触发垃圾回收,如果垃圾回收后依然不满足则抛出内存不足的异常。另外分配内存是连续分配的,而且在同一时间段里分配内存的那些对象一般都有很强的联系,比如FileStream和BinaryWriter,连续分配就会使访问命中率提高,使得性能优化。

      关键的问题在于垃圾回收器如何知道哪些对象是垃圾,哪些对象是依然在使用的呢?在CLR中,将那些不再被引用的对象被认为是可以被回收的。但对象之间有时候会存在复杂的调用关系,这个时候就需要寻根溯源,找到源头后,将这一系列的对象都标示为正在使用的,直到遍历完所有的源头,那些没被标示的就可以被认为是垃圾被回收掉。那么源头是什么呢?在CLR中有个根(root)的概念,每个应用程序都有一系列的根,根是一个存储位置,它保存着一个指向引用类型对象的指针。因此局部变量,全局变量,静态变量,方法参数以及指向托管堆中对象的CPU寄存器都是根。显然值类型变量是不会为根的。在标记和回收之后还有一个过程,夯实(compact)。 垃圾回收器扫描托管堆,找到连续的内存块,然后移动未回收的对象到更低的地址, 以得到整块的内存,同时所有的对象引用都将被调整为指向对象新的存储位置。

      CLR垃圾回收机制中还有个很重要的概念,代(generation)。其主要目的是提高垃圾回收的性能。一般分为3代:0代,1代和2代。0代是新建对象和从未经过垃圾回收对象的集合,1代则是在0代回收过程中未被回收的对象集合,2代是最后一代,也就是经历至少两次回收风暴后依然坚挺的对象的集合。

      理解不够深,感觉描述起来也比较困难,暂且先写到这,以后再补充。

      (这篇文章解释的比较清楚:http://hi.baidu.com/liyun_love_it/blog/item/83c8f73879c785fa3a87ce8a.html,参阅一下)

  • 相关阅读:
    Android防止手动添加的本地库文件被NDK工具清理掉
    将驱动编译进Linux内核
    cocos2d-x入门学习笔记——Hello world分析
    linux内核开发入门学习
    makefile工程管理
    GDB程序调试工具
    ios学习笔记_20140308
    Mac Os学习笔记-下载黑屏
    时间过得好快
    做一个关于预防接种的app
  • 原文地址:https://www.cnblogs.com/hula100/p/1729110.html
Copyright © 2011-2022 走看看