.net CLR 4.0废物回收机制的改良的3

A survey of garbage collection and the changes CLR 4.0 brings in Part 3

  • series of what is new in CLR 4.0
    接前篇Continue the previous posts

 .net CLR
4.0针对废品回收机制的改良

.net CLR
4.0针对垃圾回收机制的精益求精2

 

弱引用Weak Reference

mm小游戏

故引用是对立大引用来说的。强引用指的是穷来一个指南针指向对象。弱引用是由此对高引用加以弱化而赢得的。这个弱化的伎俩便之所以System.WeakReference类。所以精确地游说,强引用指的凡彻底来一个非WeakReference类型的指针指向对象,而死亡引用就是彻底来一个WeakReference类型的指针指向对象。垃圾收集器看到一个WeakReference类型的根指向某对象,就会特意处理。所以于垃圾收集器创建对象引用关系图的时候,如果碰到一个已故引用指针,那么垃圾收集器就不会见用其投入图被。如果一个目标仅发弱引用指向她,那么垃圾收集器可以收集者目标。一旦用一个强引用加到目标及,不管对象有没发出死引用,对象都不行回收。

 

Weak reference is corresponding to strong reference. Strong reference is
that a root is pointing to an object. Weaken a strong reference and get
a weak reference. The facility to weaken strong reference is the
System.WeakReference class.  An exact definition is that, strong
reference is that a root has a non-System.WeakReference type pointer
pointing to an object, and weak reference is that a root has a
System.WeakReference type pointer pointing to an object. Garbage
collector treats the roots of WeakReference type in a special way.
Therefore, when garbage collector is building the reference relationship
graph, if there is a weak reference pointer, and then garbage collector
will not append it to the graph. If an object only has weak references
pointing to it, garbage collector can collect the object. Once a strong
reference is pointing to the object, no matter whether the object has
weak references or not, the object can not be collected.

渣收集器对WeakReference类的特别处理打new操作就开始。通常的类,只要new操作,就见面从托管堆分配空间,而WeakReference类的new操作不是如此做的。我们先行来拘禁WeakReference类的构造函数:

The special treatment that garbage collector deals with WeakReference
class starts from the new operation. A common class will allocate space
from managed heap when new operation, but CLR does not do like that for
WeakReference class when new operation. Let’s look at the constructors
of WeakReference class:

WeakReference(Object target);

淑女小游戏

WeakReference(Object target, Boolean trackResurrection);

此二构造函数都亟待一个对象的援,第二个构造函数还得一个布尔值参数来表示我们是否要跟对象的重生。此参数的含义后文会交代。

The two constructors both need a reference of an object, and the second
constructor needs one more, a parameter of boolean type to indicate
whether we need to track the resurrection of the object. The exact
meaning of the parameter will be talked about later.

倘我们出少数单类MyClass和MyAnotherClass,都出Finalize方法。我们声明两单对象:

Suppose we have two classesMyClass and MyAnotherClass, and both of
classes have Finalize method.

MyClass myObject = new MyClass();

MyAnotherClass myAnotherObject = new MyAnotherClass();

当我们为此如此的代码声明一个过世引用对象: WeakReference
myShortWeakReferenceObject = new WeakReference( myObject );

When we use such a snippet of code to declare a weak reference object:
WeakReference myShortWeakReferenceObject = new WeakReference( myObject
);

垃圾收集器内部发生一个短弱引用表,用这么声明的故引用对象将未会见以托管堆着分配空间,而是在短弱引用表中分红一个扇。此槽中记录对myObject的援。New操作将此槽的地点返回给myShortWeakReferenceObject变量。

Garbage collector has a short weak reference table inside, the weak
reference object declared in such a way will not allocate space from
managed heap, and a slot will be allocated in the short weak reference
table for the weak reference object. The slot records the referene of
myObject. New operation returns the address of the slot to
myShortWeakReferenceObject variable.

假使我们因此这么的代码声明一个死去引用对象(我们若跟该对象的重生):
WeakReference myLongWeakReferenceObject = new WeakReference(
myAnotherObject, true );

When we use such a snippet of code to declare a weak reference object(We
need to track resurrection of the object): WeakReference
myLongWeakReferenceObject = new WeakReference( myAnotherObject, true );

垃圾收集器内部有一个增长弱引用表,用如此声明的身故引用对象将未会见以托管堆着分配空间,而是以长弱引用表中分配一个扇。此槽中著录对myAnotherObject的援。New操作将此槽的地方返回给myLongWeakReferenceObject变量。

Garbage collector has a long weak reference table inside, the weak
reference object declared in such a way will not allocate space from
managed heap, and a slot will be allocated in the long weak reference
table for the weak reference object. The slot records the referene of
myAnotherObject. New operation returns the address of the slot to
myLongWeakReferenceObject variable.

渣收集器此时底搜集流程是这般的: The collecting process of garbage
collector in this scenario is looking like the follwoing:

1.
杂质收集器建立目标引用图,来找到有的而是抵达目标。前文已经说罢怎样建图。特别之地方是,如果碰到非WeakReference指针,就进入图,如果遇WeakReference指针,就非进入图。这样图虽建造好了。Garbage
collector builds up the reference ralationship graph to find all the
reachable objects. The way to build up the graph is mentioned earlier.
The special space is, if encounters a non-WeakReference pointer, then
appends it to the graph, if meets a WeakReference pointer, then does not
append it to the graph. The graph is built in this way.

2.
垃圾收集器扫描短弱引用表。如果一个指针指向一个不在图备受的对象,那么这目标就是是一个不得到达的目标,垃圾收集器就以短弱引用表相应的槽置空。Garbage
collector scans the short weak reference table. If a pointer pointing to
an object not in the graph, then the object is not a reachable object,
and then garbage collector sets the slot to null in the short weak
reference table.

3.
破烂收集器扫描了队列。如果队列中一个指针指向一个请勿在觊觎备受之对象,此指针将于起央队列移到要了队列,同时是目标被投入引用关系图备受,因为此时此对象是Finalize可至的。Garbage
collector scans the Finalization queue. If a pointer in the queue
pointing to an ojbect not in the graph, then the pointer will be moved
to the ToBeFinalized queue, and the object will be appended to the
reference relationship graph, because the object is Finalize reachable
at this time.

4.
污染源收集器扫描长弱引用表。如果一个指南针指向一个无在觊觎中的靶子(注意这图中早已含Finalize可抵的目标),那么是目标就是一个不可到达的对象,垃圾收集器就将长弱引用表相应的槽置空。Garbage
collector scans the long weak reference table. If a pointer pointing to
an object not in the graph, then the object is not a reachable object,
and then garbage collector sets the slot to null in the long weak
reference table.

  1. 废品收集器夯实(压缩)托管堆。 Garbage collector tamps(or compacts) the
    managed heap.
    短弱引用不跟重生。即垃圾收集器发现一个目标为不可到达就即用短弱引用表相应的槽置空。如果该目标来Finalize方法,并且Finalize方法还尚未履,所以该对象就是还设有。如果应用程序访问弱引用对象的Target属性,即使该目标还设有,也会得null。

Short weak reference does not track resurrection. It means that garbage
collector sets the slot to null in the short weak reference table as
soon as finds an object not reachable. If the object has a Finalize
method, and its Finalize method has not been executed, then the object
still exists. If the applicaiton accesses the Target property of the
weak referene object, and gets null even though the object still exists.

长弱引用跟踪重生。即垃圾收集器发现一个靶是Finalize可抵达的目标,就不以相应的槽置空。因为Finalize方法还未曾实行,所以该对象就是还存在。如果应用程序访问弱引用对象的Target属性,可以获该对象;但是要Finalize方法就给实践,就标志该目标没重生。

Long weak reference tracks resurrection. It means that garbage collector
does not set the slot to null in the long weak reference table when
garbage collector  meets an object is Finalize reachable. Because the
Finalize method has not been executed, the object still exists. If the
application accesses the Target property of the weak reference object,
and gets the object. But if the Finalize method has been executed, then
the object is not resurrected.

按照地方的例证,如果实行如下代码会出什么啊?Continue the above
example, what will happen if we execute the following code?

//File: MyClass.cs
using System;
using System.Collections.Generic;
using System.Text;

namespace ConsoleApplication2

靓女小游戏打分装扮小游戏
古装公主小游戏
化妆仙女小游戏
美容男友小游戏
婚纱礼服小游戏
洋妹小打
芭比娃娃小游戏
张房间小游戏
照顾宝宝小游戏
思想测试小打
连连看
对对碰
找不同
泡泡堂
祖玛
超级玛丽
黄金矿工

{
    class MyClass
    {
        ~MyClass()
        {
            Console.WriteLine(“In MyClass
destructor+++++++++++++++++++++++++++”);
        }
    }
}//File: MyAnotherClass.cs
using System;
using System.Collections.Generic;
using System.Text;

 

namespace ConsoleApplication2
{
    public class MyAnotherClass
    {
        ~MyAnotherClass()
        {
            Console.WriteLine(“In MyAnotherClass
destructor___________________________________”);
        }
    }
}//File: Program.cs
using System;
using System.Collections.Generic;
using System.Text;

namespace ConsoleApplication2
{
    class Program
    {
        static void Main(string[] args)
        {
            MyClass myClass = new MyClass();
            MyAnotherClass myAnotherClass = new MyAnotherClass();
            WeakReference myShortWeakReferenceObject = new
WeakReference(myClass);
            WeakReference myLongWeakReferenceObject = new
WeakReference(myAnotherClass, true);
            Console.WriteLine(“Release managed resources by setting
locals to null.”);
            myClass = null;
            myAnotherClass = null;

            Console.WriteLine(“Check whether the objects are still
alive.”);
            CheckStatus(myShortWeakReferenceObject, “myClass “,
“myShortWeakReferenceObject”);
            CheckStatus(myLongWeakReferenceObject, “myAnotherClass”,
“myLongWeakReferenceObject”);

            Console.WriteLine(“Programmatically cause GC.”);
            GC.Collect();

            Console.WriteLine(“Wait for GC runs the finalization
methods.”);
            GC.WaitForPendingFinalizers();

            //Check whether the objects are still alive.
            CheckStatus(myShortWeakReferenceObject, “myClass “,
“myShortWeakReferenceObject”);
            CheckStatus(myLongWeakReferenceObject, “myAnotherClass”,
“myLongWeakReferenceObject”);

            Console.WriteLine(“Programmatically cause GC again. Let’s
see what will happen this time.”);
            GC.Collect();

            //Check whether the objects are still alive.
            CheckStatus(myShortWeakReferenceObject, “myClass “,
“myShortWeakReferenceObject”);
            CheckStatus(myLongWeakReferenceObject, “myAnotherClass”,
“myLongWeakReferenceObject”);

            myAnotherClass =
(MyAnotherClass)myLongWeakReferenceObject.Target;

            Console.ReadLine();
        }

        static void CheckStatus(WeakReference weakObject, string
strLocalVariableName, string strWeakObjectName)
        {
            Console.WriteLine(strLocalVariableName + (weakObject.IsAlive
? ” is still alive.” : ” is not alive.”));
            Console.WriteLine(strWeakObjectName + (weakObject.Target !=
null ? “.Target is not null.” : “.Target is null.”));
            Console.WriteLine();
        }
    }
}
呼吁大家想同一怀念使MyAnotherClass类没有Finalize方法呢? Please think about
what if the MyAnotherClass class does not have Finalize method.

抑或:如果我们诠释掉就行: GC.WaitForPendingFinalizers();,
试着多行是代码多次,
看看每次见面输出什么也?是免是Finzalization方法给实践之机未确定? Or, if
we comment the line: GC.WaitForPendingFinalizers();, and try to execute
the code multiple times, let’s see what will be the outputs. Is it that
the time to execute Finalization methods is uncertain?

已故引用是为充分目标准备的。在其实中,如果非用弱引用,只所以高引用,则用过了该大对象,然后以高引用置null,让GC可以回收它,但是没过多久我们以要这大目标了,但是已经没有辙探寻回本的对象,只好重新创设实例,这样就浪费了创实例所需要的盘算资源;而如不置null,就见面占有多内存资源。对于这种气象,我们得创建一个这个好目标的逝世引用,这样在内存不够时用高引用置null,让GC可以回收,而于没有叫GC回收前,如果我们缺少日外还索要该大对象,我们尚可重新寻找回该对象,不用再重新创设实例。是免是节省了有些开支?

Weak reference is for large objects. In our daily practice, if we do not
use weak reference, only use strong reference, it happens that we use a
largae object and set it to null and let GC collect it, and we need the
large object soon later, but there is no way find the original object
back, we have to instanciate a new large object. That way we are wasting
computer resources to create the old instance, but if we do not set the
object to null, it occupies lot of memory. In this case, we can create a
weak reference of the large object, and set strong reference object to
null when there is not enough memory and let GC collect the large
object, and we can find the large object back when we have requirement
before the large object has not been collected by GC. No need to create
a new instance, does this way save costs?

污染源收集的貌似流程The common process of garbage collection
以下是渣滓收集之形似流程,受应用场景(如服务器应用,并发和非并发)影响,具体的污染源回收流程可能截然不同。The
following is the common process of garbage collection, because of
different scenarios and factors(like server application scenario,
concurrent or non-concurrent), the actual processes are a little
different.

  1. 挂起.net应用的所有线程Suspend all the threads of .net application

  2. 找到可回收的目标Find all the reclaimable objects

  3. 回收而回收的目标并压缩托管堆Reclaim the reclaimable objects and
    compact the managed heap

  4. 继往开来.net应用之所有线程Resume all the threads of .net application

渣收集的模式The modes of Garbage collection
CLR4.0之前,一共来三种植模式的GC,分别指向不同档次的应用程序而优化:Server版非连发GC,
Workstation版并发GC, 和Workstation版非并发GC. Before CLR 4.0, there are
three different modes of GC, which are optimized for different types of
applications: Server version Non–concurrent GC, Workstation version
concurrent GC, and Workstation version Non-concurrent GC.

Server GC – Non Concurrent
Server
GC是针对服务器应用而展开优化的,目的是为了确保其大吞吐量和赛之范畴可扩展性。The
server non-concurrent GC is optimized for high throughput and high
scalability in server applications.

Server GC
为各级一个处理器分配一个托管堆和一个GC线程。各GC线程独立工作于分别的堆积上,这样极其老程度地减少了锁,从而保证了是种情景下之迅速。这些GC线程是非并发的(第0代表,第1代表,第2替代还是无并发的,即在搜集时犹设停下所有应用程序的线程,直到采访了)。同时这些GC线程是专程的线程,不同让应用程序的线程。The
server GC allocates one heap and one GC thread for each of processors.
The GC threads work on their respective heaps,  and this minimizes the
possibilities to lock resources, and ensures high efficiency in the
server situation. The GC threads are non-concurrent(Gen 0, Gen 1 and Gen
2 are non concurrent, meaning that garbage collector suspends all the
threads of application at collecting cycles of generations until the
collecting finishes). Meanwhile the GC threads are dedicated threads,
different from the threads of application.

实际的Server GC工作流程是如此的:The actual work flow of server GC is
looking like the following:

  1. 应用程序的线程在其托管堆上分红空间The application threads are doing
    allocations on their corresponding managed heap;

  2. 彼托管堆没有再多空间来分配托管对象They run out of allocations on the
    heaps their allocating on;

  3. 于是乎点一个事变,让GC线程来举行采访,并听候GC线程完成搜集That signals
    an event to wake the GC threads to do a GC and waits for it to finish;

4.
GC线程运行,完成搜集并发生好事件(在GC线程运行中,应用程序线程是刹车的)GC
threads run, finish with the GC and signal an event that says GC is
complete (When GC is in progress, all the application threads are
suspended);

  1. 应用程序的线程继续运行The application threads resume running.

这种类型的GC只有以多处理器的机器及可见,如果你当特处理器上的装置这种模式,那您拿抱workstation版本非并发的GC。The
Server Non-concurrent GC is only available on multi processor machines.
If you try to set the server GC on a machine with single processor you
will instead get the workstation version with non concurrent GC.

Asp.net的使在差不多cpu的机器及默认使用这种模式,还生另一些项目的服务器应用为于差不多cpu的机械及采用这种模式。例如如果您想在Windows服务及用server
GC模式,你可以于应用程序配置文件被做如下设置:ASP.NET applications use
the mode by default on multiproc machines, as well as a number of other
types of server applications. For example, if you want to use the server
GC in a windows service you can do so by setting in the application’s
config file:

<configuration>
<runtime>
   <gcServer enabled=”true” />
</runtime>
</configuration>

Workstation GC – Concurrent
Winform应用程序和Windows services 服务程序默认使用这种模式。This is the
default setting for win forms applications and windows services.

这种模式是对交互式应用程序优化的,这种程序要求应用程序不能够暂停,即使是一个针锋相对好短暂之岁月为是甚的。因为暂停进程会给用户界面闪烁或者当点击按钮的上感觉应用程序没有响应。The
Workstation GC is optimized for interactive applications that can’t
allow for the application to be paused even for relatively short periods
since pausing the threads would cause flicker in the user interface or
make the application feel non responsive to button clicks etc.

在这种模式下,第0代表以及第1替代之搜集还是是设中断应用程序的线程直到采访了,因为第0替和第1代表的收集速度快速,所以并未必要失去做并行。所谓的起是当用第2替收集时,我们可择为第2代收集并行地实施或者暂停应用程序的装有线程直到采访了。如果我们没召开选择,那么默认的即使是第2替代收集是并行的。In
this mode, the collection of gen 0 and gen 1 still need to pause all the
threads of application until the collection of gen 0 and gen 1 finishe.
Since the gen 0 and gen 1 collections are very fast, it does not make
sense to have concurrent GC when we do gen 0 and gen 1 collections. The
concurrent is that we can choose whether we do concurrent collection
when it is gen 2 collection or suspend all the threads of application
until the collection finish. If we do not make the choice, then the
default is that the gen 2 collection is concurrent.

出一个专程的GC线程来并行地收集垃圾。在第2替代收集时,用重新多CPU周期与堆内存来换取更少的用户界面停顿时间。There
is a dedicated GC thread collecting garbage in parallel mode. This is
done by trading a little bit more CPU cycles and heap memory usage for
shorter UI pause time when doing gen 2 collections.

互相收集还是要以搜集过程遭到间断应用程序多次,但就几乎差暂停相对比短,对UI线程影响比小。应用程序线程在互动收集进行着得而且分配对象。这即要求第0替出比充分之长空与比高之触发Gen
0收集的阀值。如果应用程序用了第0代之内存,而互相收集还没有开展完,那么应用程序不得不中止下来,等待并行收集的好。Concurrent
collection still needs to suspend the application multiple times during
the concurrent collecting cycle. , but the the times of pause are
shorter than usual, have less impact on the UI thread. The application
can allocate objects while the concurrent collection is going on. This
requires that the gen 0 has bigger space and higher threshold to trigger
collection on gen 0. If the application exhausts the memory of gen 0,
and the concurrent collection is not finished, then the application has
to suspend to wait for the concurrent collection finishes.

设若我们要做取舍,让应用程序在竞相模式下运行,可以以应用程序的config文件中描绘上:
If we make the choice to let the application run under concurrent mode,
please leave this in the config file of the application.

<configuration>

<runtime>

<gcServer enabled=“true”/>

</runtime>

</configuration>

流淌: Jeffrey Richter似乎在其书<<CLR via c#>>中说concurrent
GC只来于差不多CPU机器上出。但是透过Mark的调查,实际上concurrent
GC在单CPU上吧发生。

Note: Jeffrey Richter seemed to mention in his book <<CLR via
c#>> that concurrent GC is only available on multiple CPUs
machine, but according to Mark’s investigation, concurrent GC is also
available on single CPU machine.

Workstation GC – Non Concurrent
这种模式和Server
GC类似,推荐吧那种运行于单个cpu机器上服务类型的应用程序使用。与Server
GC不同的凡:其募集线程即同于应用程序线程。这是这种模式之行事流程:The
mode is similar to the Server GC mode, and is recommended for the server
applications running on single processor machine. The collection happens
on the same threads of application, which is different from what the
Server GC does. The following is the work flow of the mode:

1) 应用程序线程在积上分红对象Application threads are doing allocations
on the heap;

2) 第0替代没有足够空间It runs out space in gen 0.

3) 在同一线程上掀起垃圾收集It triggers a GC which will be running on
this very thread;

4) 垃圾收集器调用SuspendEE函数暂停应用程序线程GC calls SuspendEE to
suspend the application’s threads;

5) GC做采访工作GC does its work;

6) GC调用RestartEE来继承应用程序的线程GC calls RestartEE to restart the
application’s threads;

7) 应用程序的线程继续运行Application threads start running again.

足改应用程序的部署来拿 concurrency 关闭。We could close concurrency
using the following setting in the application’s config file.

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

下面是三种植模式之对比表This is the comparison matrix of the modes:

  Concurrent WS
 Non-Concurrent WS
 Server GC
 
Design Goal
 Balance throughput and responsiveness for client apps with UI
 Maximize throughput on single-proc machines
 Maximize throughput on MP machines for server apps that create multiple
threads to handle the same types of requests
 
Number of heaps
 1
 1
 1 per processor (HT aware)
 
GC threads
 The thread which performs the allocation that triggers the GC
 The thread which performs the allocation that triggers the GC
 1 dedicated GC thread per processor
 
Execution Engine Suspension
 EE is suspended much shorter but several times during a GC
 EE is suspended during a GC
 EE is suspended during a GC
 
Config setting
 <gcConcurrent enabled=”true”>
 <gcConcurrent enabled=”false”>
 <gcServer enabled=”true”>
 
On a single processor machine
     WS GC + non-concurrent
 
 

上述我们说及了CLR 4.0以前垃圾收集之大部分地方。
掌握前面的学识有助于了解CLR 4.0所带来的成形。We introduced most of
aspects of garbage collection prior to CLR 4.0. Master the legacy to
help undetstand the changes CLR 4.0 brings in.

CLR 2.0以后GC有哪些变化吧?What are the changes since CLR 2.0?
CLR V4.0拉动的后台垃圾收集The background GC brought to you by CLR 4.0
面前我们都关系曾经来矣起垃圾收集。后台垃圾收集是来替并发垃圾收集。后台垃圾收集是出现垃圾收集的迈入。We
mentioned there has been concurrent GC. Background GC is to replace
concurrent GC. Background GC is an evolution to concurrent GC.

当应用程序的活动量不大(包括分配与修改引用)并且堆不太怪时,并作垃圾收集工作得好。由并发垃圾收集带来的缓是可领之。但是当众人编写更充分的应用程序,需要运用更可怜的堆,这时由并发收集带来的延迟就变换得不行接受。When
the program activity (including making allocations and modifying
references) is not really high and the heap is not very large concurrent
GC works well – the latency caused by the GC is reasonable. But as
people start writing larger applications with larger heaps that handle
more stressful situations, the latency can be unacceptable.

后台垃圾收集的显而易见改进是:在后台垃圾收集进行着,如果需要的话,我们可开少的废料收集(第0代表与第1替代收集)。与出新垃圾收集类似,后台垃圾收集也是只有当尽废物收集时才生。并且缺乏的杂质收集(第0代表与第1替代收集)总是以阻断方式开展垃圾收集(暂停应用程序)。后台垃圾收集在一个特别的线程上运行。那些跟后台垃圾收集而开展的紧缺垃圾收集(第0代表与第1替代收集)被称呼前台垃圾收集。

The significance of background GC is we can do ephemeral GCs(gen 0 and
gen 1 GC) while a background GC is in progress if needed. As with
concurrent GC, background GC is also only applicable to full GCs and
ephemeral GCs are always done as blocking GCs(suspend the application),
and a background GC is also done on its dediated GC thread. The
ephemeral GCs(gen 0 and gen 1 GC) done while a background GC is in
progress are called foreground GCs.

于是,当后台垃圾收集正开展着一经第0代表空间欠缺,就见面接触一个第0替垃圾收集(有或提升变成第1代收集,取决于垃圾收集器的其中决策)。后台垃圾收集线程会经常检查安全点(比如前台垃圾收集发出)。当有前台垃圾收集时,后台垃圾收集会自己暂停并被前台垃圾收集好开开工作。在前台垃圾收集得以后,后台垃圾经常线程和应用程序的线程就继续她的做事。

So when a background GC is in progress and you’ve allocated enough in
gen0, we will trigger a gen0 GC (which may stay as a gen0 GC or get
elevated as a gen1 GC depending on GC’s internal tuning). The background
GC thread will check at frequent safe points (ie, when we can allow a
foreground GC to happen) and see if there’s a request for a foreground
GC. If so it will suspend itself and a foreground GC can happen. After
this foreground GC is finished, the background GC thread and the user
threads can resume their work.

后台垃圾收集不仅于较逊色之代将无济于事的目标清除,同时它提高了目标停留于短缺生命周期段的限–如果后台垃圾收集进行着需扩大堆,我们得以第1代表收集时如此做。而立当CLR1.0以及CLR2.0特出于第2代收集时才见面生。

Not only does this allow us to get rid of dead objects in young
generations, it also lifts the restriction of having to stay in the
ephemeral segment – if we need to expand the heap while a background GC
is going on, we can do so in a gen1 GC. In CLR1.0 and CLR 2.0, this only
happens when gen 2 GC .

后台垃圾收集比并作收集之补体现于:在后台采访进行着,应用程序耗尽了第0替代之上空,如果是起收集,应用程序必须暂停为伺机并发收集得。而现不可同日而语了,可以为此前台收集对第0替或第1代表进行采。于是就无须等。同时,如果欲,可以于第1替代收集就扩大堆(增加内存段),而不用等及第2替收集。这减少了给UI应用程序暂停的火候。Advantages
of Background GC(versa to concurrent GC) are : During background GC, the
application runs out memory in gen 0, if it is concurrent GC, the
application has to suspend and wait for the finish of concurrent GC. But
now it is different, we can use forground GC to do collection on gen 0
or gen 1. therefore no need to wait for the finish of concurrent GC. And
meanwhile, we can expand the heap(by adding new memory segment) at gen 1
if required, do not have to wait until gen 2 GC. These minimize the
possibilities to suspend the UI application.

我们通过互动地召开更多工作改进了后台垃圾收集之习性,所以用暂停应用程序线程的日子又缺乏。我们现不曾当CLRV4.0被吗Server
GC提供后台垃圾收集。那将是继承的工作。We also made some performance
improvement in background GC which does better at doing more things
concurrently so the time we need to suspend managed threads is also
shorter. We are not offering background GC for server GC in V4.0. That
is coming work.

.net 3.5 SP1中的周采集通报机制Full GC notification in .net 3.5 SP1
万事征集通报机制是为负大量告的服务器应用准备的。因为在有的动静,CLR的整个募集会带动比较充分之推移,从而影响服务器应用的性能,导致用户请求过。针对这种状态,全部集通报机制起。当一个均垃圾收集将要开始经常,你晤面获得通知并可以采用相应动作,如将请求导向别的服务器。

.net 3.5 SP1的GC类增加了几单方法:

GC.RegisterForFullGCNotification

GC.WaitForFullGCApproach

GC.WaitForFullGCComplete

GC.CancelFullGCNotification

连当System命名空间下多了一个枚举

GCNotificationStatus

本条GC.RegisterForFullGCNotification
用来注册时动将接收全部破烂收集之通。当一个全勤废弃物收集将要发生常,注册了底应用程序就只是接受通知。同时,当一个全副废弃物收集好时,注册了之次第为会接到通知。这是GC.RegisterForFullGCNotification
的申方式:

[PermissionSetAttribute(SecurityAction.LinkDemand, Name =
“FullTrust”)]
public static void RegisterForFullGCNotification(
    int maxGenerationThreshold,
    int largeObjectHeapThreshold
)maxGenerationThreshold是1-99次的数.指的是第2代表中现有的靶子个数达到这个阀值就要通知.
largeObjectHeapThreshold也是1-99期间的数.指的凡老目标堆中分红的目标个数达到这阀值就要通知.

WaitForFullGCApproach用来获取垃圾收集器是否将进行整垃圾收集.
它的扬言是这般的:

[PermissionSetAttribute(SecurityAction.LinkDemand, Name =
“FullTrust”)]
public static GCNotificationStatus
WaitForFullGCApproach()或者[PermissionSetAttribute(SecurityAction.LinkDemand,
Name = “FullTrust”)]
public static GCNotificationStatus WaitForFullGCApproach(
    int millisecondsTimeout
)第2只调用方式得以拉动一个等待时, 单位凡毫秒.
其回到的凡枚举GCNotificationStatus,
如果是GCNotificationStatus.Succeeded,
那么我们虽可以以呼吁导向其他服务器.与WaitForFullGCApproach类似的,
WaitForFullGCComplete用来取得垃圾收集器是否就形成整个垃圾堆收集,
它的扬言是如此的:

[PermissionSetAttribute(SecurityAction.LinkDemand, Name =
“FullTrust”)]
public static GCNotificationStatus WaitForFullGCComplete()或者

[PermissionSetAttribute(SecurityAction.LinkDemand, Name =
“FullTrust”)]
public static GCNotificationStatus WaitForFullGCComplete(
    int millisecondsTimeout
)第2个调用方式可带动一个候时, 单位是毫秒.
其返回的是枚举GCNotificationStatus,
如果是GCNotificationStatus.Succeeded,
那么我们即便可以用以此服务器再声明可以承受外的请求.

WaitForFullGCApproach和WaitForFullGCComplete设计时就是要联手用的。如果仅使一个设未行使任何一个纵会见招致不可知的结果。

GC.CancelFullGCNotification是因此来用曾经报的杂质收集通报取消.
与GC.RegisterForFullGCNotification 一起成为对郎才女貌使用.

寻常的使方法是如此的:

1.率先以主线程调用GC.RegisterForFullGCNotification 来准备取通知

2.起动一个值守线程,
在值守线程中调用WaitForFullGCApproach和WaitForFullGCComplete来收获当前GC状态,
如果是快要进行全方位废品收集,就做相应处理,如以请求导向其他服务器。如果是全部废品收集了,则只是举行相应处理,
如将以此服务器标记为而承受请求.值守线程中需要不断循环来轮循GC状态.

3.当主线程将要结束, 调用GC.CancelFullGCNotification并发消息通知值守线程,
值守线程退出循环,结束.

4.主线程退出

对于asp.net应用,
可以在Application_Start中调用GC.RegisterForFullGCNotification并启动一个值守线程.
又可以于Application_End中通值守线程结束.

全套垃圾堆收集通报机制的突出用途就是是以差不多服务器的场景.心理测试用NLB(Network load
balance)搭建的Web Farm或者硬件load balance的多服务器场景.
一个比较复杂的场面是每个服务器上还有web garden设置.

注意事项: 全部破烂收集通报机制只有当非并发模式时才不过用.
WinForm和Console应用还是默认为出现模式.
例如msdn上之杀例子程序,就用以先后的app.config中添加

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

全文完. 谢谢各位!

参考文献References

Garbage Collection: Automatic Memory Management in the Microsoft .NET
Framework By Jeffrey Richter 
http://msdn.microsoft.com/en-us/magazine/bb985010.aspx

Garbage Collection Part 2: Automatic Memory Management in the Microsoft
.NET Framework By Jeffrey Richter
http://msdn.microsoft.com/en-us/magazine/bb985011.aspx

Garbage Collector Basics and Performance Hints By Rico Mariani at
Microsoft  http://msdn.microsoft.com/en-us/library/ms973837.aspx

http://drowningintechnicaldebt.com/blogs/royashbrook/archive/2007/06/22/top-20-net-garbage-collection-gc-articles.aspx

Large Object Heap Uncovered By Maoni Stephens
http://msdn.microsoft.com/en-us/magazine/cc534993.aspx

Garbage collection in msdn
http://msdn.microsoft.com/en-us/library/0xy59wtx.aspx

How does the GC work and what are the sizes of the different
generations?  By Tess Ferrandez 
http://blogs.msdn.com/tess/archive/2008/04/17/how-does-the-gc-work-and-what-are-the-sizes-of-the-different-generations.aspx

So, what’s new in the CLR 4.0 GC? By Maoni Stephens
http://blogs.msdn.com/maoni/archive/2008/11/19/so-what-s-new-in-the-clr-4-0-gc.aspx

Using GC Efficiently – Part 1
http://blogs.msdn.com/maoni/archive/2004/06/15/156626.aspx

Using GC Efficiently – Part 2
http://blogs.msdn.com/maoni/archive/2004/09/25/234273.aspx

Using GC Efficiently – Part 3
http://blogs.msdn.com/maoni/archive/2004/12/19/327149.aspx

Using GC Efficiently – Part 4
http://blogs.msdn.com/maoni/archive/2005/05/06/415296.aspx

The mystery of concurrent GC 
http://www.julmar.com/blog/mark/PermaLink,guid,3670d081-0276-48e6-b97d-1b644093b52e.aspx

http://blogs.msdn.com/clyon/archive/2004/09/10/228104.aspx

http://blogs.msdn.com/clyon/archive/2004/09/08/226981.aspx

http://msdn.microsoft.com/en-us/library/cc713687.aspx

You can leave a response, or trackback from your own site.

Leave a Reply

网站地图xml地图