垃圾回收——代

发表于:2011-12-30 09:31

字体: | 上一篇 | 下一篇 | 我要投稿

 作者:陈太汉    来源:51Testing软件测试网采编

  代是CLR垃圾回收器采用的一种机制,他唯一的目的就是提升应用程序的性能,采用代的垃圾回收器做到了一下几点:

  1、对象越新,生存周期越短,跟栈的原理很像,先进后出,先定义的局部变量,在栈中停留的时间相对长一点。

  2、对象越老,生存周期越长,后面解释。

  3、回收堆的一部分,速度快于回收整个堆,那是肯定的,就是为了实现只回收一部分内存中的数据,才产生了代的概念,大多数时间只回收第0代。

  第0代:托管堆在初始化的时候不包含任何对象,新分配在堆上的对象被称为第0代,垃圾回收器从没有检查过他,CLR在初始化的时候,会为第0代预算了一个容量,假设为256KB,容量一般为128KB的整数倍,这跟CPU的L2缓存容量有关,CPU的L2缓存容量经历了128KB,256KB,512KB,1M......,就是为了让第0代中的数据能全部装入CPU的L2缓存中,这样处理数据会更快。

  第1代:如果在分配一个新对象时,使第0代中的数据超过其预算容量,就会发生垃圾回收,不能到达的数据就会被回收,不能到达就是没有被任何对象引用,有被引用当然就不会被回收,没有被回收的数据,被称为第1代,第一代的容量比第0代的大,假设为2M,经过一次垃圾回收后第0代不包含任何数据。只要第1代没有就不会回收。

  新产生的对象永远被分配在第0代中,第0代中的数据满了,就发生垃圾回收,将没有被回收的对象压缩至第1代,数据压缩相当耗性能,就是把数据从内存在的A出复制到内存的B处,只要第1代中的数据没有满,垃圾回收器就只会回收第0代中的数据,这就是部分回收,当第1代中的数据满了,垃圾回收器就会同时回收第0代和第1代,第0代没有被回收的数据就会被压缩到第1代中,直至第1代也满。

  第2代:当第1代中的数据满了,就会回收第1代,没有被回收的数据就被称为第2代,第2代的容量大于第1代,托管堆只支持3代,第0代,第1代,第2代。

  CLR假设新生成的对象生存周期较短,所以每次回收第0代都能回收大量内存,所以CLR总是针对第0代疯狂的回收,这样效率高吗?哈哈哈!这样可能导致第0代被回收了很多次,第1代一次也没有被回收,当然第1代中大垃圾也就没有被回收,CLR假设活得比较久的对象能继续活下去,这就是对象越老,生存周期越长。

  托管堆只实现部分回收,即回收第0代,由于第0代的容量较小,所以每次垃圾回收的速度较快,当然也会因为第0代容量较小,发生垃圾回收的频率会高一些,为了得到更好的垃圾回收性能,所以第0代的容量是动态的,如果每次执行垃圾回收,所有的垃圾都被回收了,那么托管预算第0代的容量就会减少,这样可以加快垃圾回收的速度,如果每次执行垃圾回收,都有大量的垃圾没有被回收,从第0代变成第1代,托管堆就会将第0代的预算容量变大,这样可以减少数据的转移。数据的转移就相当于整理内存碎片,对程序的性能,影响还是蛮大的。

  只回收第0代的还有一个好处就是,如果第0代中的数据引用了第1代中的数据,第1代中的数据不用被检查,第1代中被引用的对象内部结构,垃圾回收器也不会管,回收更快啊,当然第1代中的数据也可能引用第0代中的数据,若第1代中的对象引用了第0代中的对象,第1代中的对象就会被标记,只有重上一次垃圾回收到下一次垃圾回收被标记的对象才会被检查,当然要检查第1代中的数据啊,你不检查第1代中的数据,你怎么知道第0代中的数据不可到达,没有被引用呢,第1代中,只有被标记的对象才会被检查,这样同样能提高垃圾回收的性能。总之,微软设计的这个垃圾回收器处处在提高你的程序性能,他是这么说的,你感觉到了吗?

  如果回收3代还是没有内存可分配,就抛出一个OutOfMemoryException异常,告诉你没有内存可分配了,以前在开发一个项目中就偶尔抛出这个异常,当时我们都不知道怎么回事,原因就是我们构造一个大的Json对象,用的是string+string,导致内存被吃光了,要是当时知道用StringBuilder,性能将会大大的提高,也不至于OutOfMemoryException异常啊,哈哈哈。

《2023软件测试行业现状调查报告》独家发布~

关注51Testing

联系我们

快捷面板 站点地图 联系我们 广告服务 关于我们 站长统计 发展历程

法律顾问:上海兰迪律师事务所 项棋律师
版权所有 上海博为峰软件技术股份有限公司 Copyright©51testing.com 2003-2024
投诉及意见反馈:webmaster@51testing.com; 业务联系:service@51testing.com 021-64471599-8017

沪ICP备05003035号

沪公网安备 31010102002173号