什么是应用程序根

摘要:
但是CIL代码允许分配全局对象)(2)指向任何静态对象(3)指向应用程序代码中的本地对象(4)指向传递到函数中的对象参数(5)指向等待完成的对象(6)指向垃圾收集期间对象的任何CPU寄存器,运行时环境检查托管堆上的对象是否仍然可以从应用程序根访问。请注意,垃圾收集器从不在图形上标记对象两次。

简单来说,一个根是一个引用,这个引用指向堆上面的一个对象的。严格来说,一个根可以有以下几种情况:

   (1) 指向全局对象的引用(尽管C#不支持,但CIL代码允许分配全局对象)

  (2) 指向任何静态对象

  (3) 指向一个应用程序代码中的局部对象

  (4) 指向传入到一个函数中的对象参数

  (5) 指向等待被终结(finalized)的对象

  (6) 任何一个指向对象的CPU寄存器

在一次垃圾回收的过程中,运行环境会检查托管堆上面的对象是否仍然是从应用程序根可到达的。为了检查可达,CLR会建立一个代表堆上每个可达对象的图。对象图用来记录所有可达的对象。同时,注意垃圾回收器绝不会在图上标记一个对象两次,因此避免了烦人的循环引用。

  假设托管堆上有名字为A,B,C,D,E,F和G的对象集合。在一次垃圾回收过程中,会检查这些对象(同时包括这些对象可能包含的内部对象引用)是否是根可达的。一旦图被建立起来,不可达的对象(在此是对象C和F)被标记为垃圾。

  下图是上述场景的一个可能的对象图(你可以把箭头读作依赖或者需要,例如"E依赖于G,间接依赖于B,“A不依赖任何对象”等)。

什么是应用程序根第1张

(创建的对象图是用来决定哪些对象是应用程序根可达的。)

  一旦一个对象已经被标记为终结(此例子中是C和F--在图中没有他俩),它在内存中就被清理掉了。在此时,堆上的剩余内存空间被压缩,这会导致CLR修改活动的应用程序根集合(和对应的指针)来指向正确的内存位置(这个操作是自动透明的)。最后,调整下一个对象指针来指向下一个可用的内存位置。

  下图阐明了清除和压缩堆的过程。

什么是应用程序根第2张

到这里,通过对应用程序根的作用的理解,我们知道了如何知道一个对象是“不再需要”的。通俗点来说就是,这个对象在应用程序中已经无需被访问了,成为了一座“孤岛”,自然也就不再需要它了。

摘抄:https://www.cnblogs.com/MaMaNongNong/p/11945161.html

标题:谈谈.net对象生命周期

理解对象的代 — 垃圾回收过程的优化

  在尝试找到不可达的对象时,CLR并不是检查托管堆上的每个对象。很明显,这样做会消耗大量时间,尤其在大型(例如现实中)程序中。

  为了帮助优化这个过程,堆上的每个对象被分配到一个特殊的"代”。代这个概念背后的想法很简单:对象在堆上存活的时间越长,接下来它继续存在的可能性也就越大,即较旧的对象生存期长,较新的对象生存期短。例如,实现Main()的对象一直在内存中,直到程序结束。相反,最近才被放到堆中的对象(例如在一个函数范围里分配的对象)很可能很快就不可达。

  在堆上的每个对象属于以下的某一个代:

    Generation 0: 标识一个最近分配的还没有被标记为回收的对象

  Generation 1: 标识一个经历了一次垃圾回收而存活下来的对象(例如,他被标记为回收,但由于堆空间够用而没有被清除掉)

  Generation 2:标识一个经历了不止一轮垃圾回收而存活下来的对象。

  垃圾回收器首先会检查generation 0的所有对象。如果标记并清理这些对象(译者注:因为新对象的生存期往往较短,并且期望在执行回收时,应用程序不再使用第 0 级托管堆中的许多对象)后产生了足够使用的内存空间,任何存活下来的对象就被提升到Generation 1。为了理解一个对象的代如何影响回收的过程,可以查看下图。下图解释了generation 0中一次垃圾回收后,存活的对象被提升的过程。  

什么是应用程序根第3张

(generation 0 中的存活对象被提升到generation 1)

  如果所有的generation 0对象都被检查了,但是产生的内存空间仍然不够用,就检查一遍generation 1中的所有对象的可达性并回收。存活下来的generation 1对象被提升到generation 2。如果垃圾回收器仍然需要额外的内存,generation 2的对象就经历检查并被回收。此时,如果一个generation 2的对象存活下来,它仍然是一个generation 2的对象。

  其实通过对象的代的设计是想达到这么一个效果:新对象(比如局部变量)会被很快回收,而老一些的对象(如一个应用程序对象)不会被经常骚扰

  说到底,对象代的设计就是为了优化垃圾回收的过程。  

构建可终结对象 — 非托管资源处理第一式

  以一名c#开发者的直觉告诉你,大多数的c#类都不需要显式的清理逻辑。原因很简单:如果类型使用了其他托管对象,一切都最终会被垃圾回收。

  问:那在什么时候需要显式地清理呢

  答案是:在你使用非托管资源时(例如原始的操作系统文件句柄、原始的非托管数据连接或其他非托管资源),才可能需要设计一个在用完后清理自身垃圾的类

  比如说下面这个类:

//数据库上下文类
   public class SqlDbContext
   {
       //...(其他被引用的对象实例)

       //类中包含的非托管资源(需要调用 Dispose()函数进行资源的释放)
       SqlConnection sqlConnection = new SqlConnection("...");  
            
   }

免责声明:文章转载自《什么是应用程序根》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇ACM/IOI 历年国家集训队论文集和论文算法分类整理(php)实现万年历下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

IOS 内存管理

  软件运行时会分配和使用设备的内存资源,因此,在软件开发的过程中,需要进行内存管理,以保证高效、快速的分配内存,并且在适当的时候释放和回收内存资源。 一、Objective-C内存管理的对象   IOS开发中,内存中的对象主要有两类,一类是值类型,比如int、float、struct等基本数据类型,另一类是引用类型,也就是继承自NSObject类的所有的...

Linux电源管理研究笔记—gnomepowermanager的工作原理

Linux电源管理研究笔记—gnome-power-manager的工作原理   转载时请注明出处:http://blog.csdn.net/absurd/   在手持设备设计中,电源管理历来为重要的研究课题之一。我们日常所说的省电就属于电源管理的范畴,这也是我们最关心的一个部分。通过挂起不必要的设备、降低CPU的频率或者其它方法,可以减少能量的消耗,达到...

Unity你用过哪些设计模式?你熟悉的设计模式有哪几种呢?

以前写过几篇设计模式的详细解释,今天在这里不详细介绍,有兴趣了解的可以去看前几篇随笔,今天就简单的介绍我们常用的设计模式. (1)工厂模式 简单工厂模式解决的问题是如何去实例化一个合适的对象. 简单工厂模式的核心思想就是:有一个专门的类来负责实例过程,范式出现大量产品需要创建,并且具有共同的接口时,可以通过工厂方法模式进行创建,比如说写技能是一系列类,那么...

DLL发布 matlab代码发布

https://blog.csdn.net/alansss/article/details/81320548 最近需要将写好的matlab代码转成基于OpenCV的代码,然后再封装成dll进行发布。一开始直接看基于OpenCV的dll生成,但是都不太成功,故而先试试没有OpenCV的dll生成。 主要参考了以下两个网页:  VS2013生成dll及动态调用...

poi excel给单元格增加批注(包含SXSSF)及设置列类型

import org.apache.poi.xssf.usermodel.*; import java.io.FileOutputStream; import java.io.IOException; public class PoiAddComments { public static void main(String[] args) thr...

配置arm linux Qt开发环境

配置arm linux Qt开发环境的过程相对比较复杂,所以有必要把步骤记录一下。 版本:Ubuntu10.04 LTS / Qt SDK 4.7.3 / arm-linux-gcc 4.4.3 一、安装arm-linux-gcc编译器 1.下载arm-linux-gcc-4.4.3,http://ishare.iask.sina.com.cn/f/138...