【译】让垃圾回收器高效工作(二)

这篇文章我们谈谈GC的不同工作模式,以及各个模式如何工作和他们之间的不同,让你明白你的应用程序该如何选择工作模式。

迄今为止运行时GC工作模式:

1)关闭并发的工作站GC
2)开启并发的工作站GC
3)服务器GC

如果你在写一个独立的托管程序并且没有做任何配置,你使用的GC工作模式是开启并发的工作站GC。这一点多数人可能会感到惊讶,因为我们的文档中并没有提起并发GC,有时候会把并发GC称为”background GC”(while referring working GC as “foreground GC”).

如果你的程序在宿主程序中运行,宿主可能会为程序选择GC的工作模式。

需要注意的是:如果你的程序配置成服务器GC,你的程序运行在一台高性能的机器上,实际上你的服务器是运行在“关闭并发的工作GC”模式下。因为“关闭并发的工作站GC”为高性能服务器的大吞吐量服务做了优化。

各个GC模式的设计目标:

1) 关闭并发的工作站GC为高性能服务器的高吞吐量做了优化。我们在垃圾回收时根据分配和复活模式做动态调优因此可以程序运行时自动调优GC的工作效率。
2) 开启并发的工作站GC是为要求精确响应时间的交互式应用程序设计的。开启并发使垃圾回收造成的工作进程暂停时间缩短。 这个目的是用一些内存和CPU换来的,因此在这种模式下垃圾回收需要做的工作略多一点需要的回收时间会略长一些。
3) 服务器GC,从名字上我们可以看出这种工作模式是为服务器应用程序设计的;典型的场景是你有一个工作线程池这些线程坐着相似的处理。例如:做处理同样的请求或者处理相同类型的事务。所有的线程使用几乎相同的分配模式。服务器GC是为要求高吞吐量的和高扩展性的多处理器服务器设计的

各个GC模式如何工作:

让我们从关闭并发的工作站GC说起,其执行流程如下:
1) 一个托管进程做内存分配
2) 分配完所有可用的内存(我会解释这是什么意思)
3) 触发了垃圾回收,垃圾回收操作在做分配的线程上运行
4) GC调用SuspendEE来挂起所有的托管线程
5) GC开始工作
6) GC调用RestartEE来重启工作托管进程
7) 托管进程继续运行

你可以看到在第5步中所有的托管线程都停止执行来等待垃圾回收完成工作。SuspendEE不会挂起本地线程(native threads)。
GC中的每一代都有一个“分配预算”的概念。每一代的“分配预算”在运行时是动态调整的。因为我们经常在0代上做分配,你可以想象0代预算超支了,这样就会触发垃圾回收。这里的预算和GC堆的段大小完全不是一回事,预算比段大小要小得多。

CLR垃圾回收可以做内存移动也可以不做移动。不做移动时也称为“清扫”,清扫的代价要比做压缩的代价低一些,因为他不需要复制移动内存。

在开启并发垃圾回收(Concurrent GC)时,最大的差异是挂起和重启。 我前面提到并发GC允许更少的暂停时间。因此开启并发的垃圾回收会尽可能少的执行垃圾回收,执行时间也非常短。在剩余的时间中如果需要托管线程可以运行和分配内存。开启并发时我们会在开始时给0代一个很大的分配预算来保证垃圾回收运行期间有足够的空间分配对象。尽管如此,如果在并发回收运行中托管线程需要分配过多的内存,线程也会被堵塞直到回收完成。

记住0代和1代回收非常快,所以在做0,1代回收时是不会做并发回收的。我们只是在2代回收时才会并发回收。如果我们决定做2代回收,我们会决定是否并发回收。

服务器垃圾回收,这种模式和前两种完全不同。我们会为每一个CPU创建一个回收线程。垃圾回收在这些线程上执行而不是在分配线程上,其工作流程如下:
1. 一个托管线程做回收
2. 分配达到阀值
3. 给GC线程发信号,让GC线程做垃圾回收,等待回收结束
4. GC线程运行,结束时发出回收完成的信号(在回收过程中,所有的托管线程会像工作站模式中一样被挂起)
5. 托管线程收到信号重新开始运行

如果配置各个垃圾回收模式:
要关闭并发回收,在配置文件中添加下面配置项:

<configuration>
<runtime>
<gcConcurrent enabled="false"/>
</runtime>
</configuration>

要使用服务器GC,使用下面配置:

<configuration>
<runtime>
<gcServer enabled=“true"/>
</runtime>
</configuration>

关于这两个配置节可以参考msdn。

原文:
http://blogs.msdn.com/b/maoni/archive/2004/09/25/234273.aspx

原作者:Maoni Stephens

相关随笔:

让垃圾回收器高效工作(一)

.Net 垃圾回收机制原理(一)

.Net 垃圾回收机制原理(二)

.Net 垃圾回收和大对象处理 


更多参考资源:
http://blogs.msdn.com/b/tess/archive/2008/04/17/how-does-the-gc-work-and-what-are-the-sizes-of-the-different-generations.aspx
http://odetocode.com/Blogs/scott/archive/2004/07/16/server-or-workstation-garbage-collection.aspx
http://msdn.microsoft.com/en-us/library/yhwwzef8.aspx
http://msdn.microsoft.com/en-us/library/ms229357.aspx

posted @ 2011-11-29 08:42  玉开  阅读(4286)  评论(11编辑  收藏  举报