.net垃圾回收和CLR 4.0对垃圾回收所做的改进之一

A survey of garbage collection and the changes CLR 4.0 brings in - series of what is new in CLR 4.0

导言Introduction

  垃圾回收(Garbage Collection)在.net中是一个很重要的机制. 本文将要谈到CLR4.0对垃圾回收做了哪些改进. 为了更好地理解这些改进, 本文也要介绍垃圾回收的历史.  这样我们对整个垃圾回收有一个大的印象. 这个大印象对于我们掌握.net架构是有帮助的.

  Garbage Collection is an important component of .net. The post will talk about what has been improved in CLR 4.0. To understand it, I will take a survey of the history of garbage collection. This way we can have a big picture of garbage collection. This will help us master .net architecture in comprehensive manner.

关于垃圾回收About Garbage collection

  在C++时代,我们需要自己来管理申请内存和释放内存. 于是有了new, delete关键字. 还有的一些内存申请和释放函数(malloc/free). C++程序必须很好地管理自己的内存, 不然就会造成内存泄漏(Memory leak). 在.net时代, 微软为开发人员提供了一个强有力的机制--垃圾回收. 垃圾回收机制是CLR的一部分, 我们不用操心内存何时释放, 我们可以花更多精力关注应用程序的业务逻辑. CLR里面的垃圾回收机制用一定的算法判断某些内存程序不再使用,回收这些内存并交给我们的程序再使用.

  In the times of C++, we need to allocate and release memory by ourselves carefully,  therefore there are new, delete keywords in C++, and fuctions(malloc/free) to allocate and release memory. C++ program has to manage its memory well, otherwise there will be memory leak. In .net, Microsoft provides a strong machanism to developers—Garbage collection. The Garbage collection is part of CLR. We do not need to worry about when to release memory. We can spend more time on buisness logic of applications. The Garbage colleciton of CLR adopts algorithms to decide which part of memory the program does not need any more, and then release these memory for further use.

垃圾回收的功能The functionalities of Garbage collection

  用来管理托管资源和非托管资源所占用的内存分配和释放。In charging of the releasing and re-allocation of memory of managed and unmanaged resources.

  寻找不再使用的对象,释放其占用的内存, 以及释放非托管资源所占用的内存. Find the objects no longer needed, release the memory the objects occupied, and affranchise memory occupied by unmanaged resources.

  垃圾回收器释放内存之后, 出现了内存碎片, 垃圾回收器移动一些对象, 以得到整块的内存,同时所有的对象引用都将被调整为指向对象新的存储位置。After releasing the memory no longer needed, there is memory scrap. Garbage collector shifts objects to get consecutive memory space, and then the references of objects will be adjusted according to the shifted address of objects.

下面我们来看看CLR是如何管理托管资源的. Let’s see how CLR takes care of managed resources.

托管堆和托管栈Managed heap and Managed stack:

.net CLR在运行我们的程序时,在内存中开辟了两块地方作不同的用处--托管栈和托管堆. 托管栈用来存放局部变量, 跟踪程序调用与返回. 托管堆用来存放引用类型. 引用类型总是存放于托管堆. 值类型通常是放在托管栈上面的. 如果一个值类型是一个引用类型的一部分,则此值类型随该引用类型存放于托管堆中. 哪些东西是值类型? 就是定义于System.ValueType之下的这些类型:

bool byte char decimal double enum float int long sbyte short struct uint ulong ushort

When .net CLR runs our program, CLR declares two ranges of memory for different purposes. Managed stack is to store local variables, and trace the call and return of routines. Managed heap is to store reference types. Usually value types was put on managed stack. If a value type is a part of a reference type, then the value type will be stored in managed heap along with the reference type. What are value types? They are the types defined in System.ValueType:

bool byte char decimal double enum float int long sbyte short struct uint ulong ushort

什么是引用类型呢? 只要用class, interface, delegate, object, string声明的类型, 就是引用类型.  What are reference types? The types declared with class, interface, delegate, object, stirng, are reference types.

我们定义一个局部变量, 其类型是引用类型. 当我们给它赋一个值, 如下例:We declare a local variable, which is a reference type, and we assign a value to the local variable, like the following:

private void MyMethod()
{
   MyType  myType = new MyType();
   myType.DoSomeThing();
}
在此例中, myType 是局部变量, new实例化出来的对象存储于托管堆, 而myType变量存储于托管栈. 在托管栈的myType变量存储了一个指向托管堆上new实例化出来对象的引用. CLR运行此方法时, 将托管栈指针移动, 为局部变量myType分配空间, 当执行new时, CLR先查看托管堆是否有足够空间, 足够的话就只是简单地移动下托管堆的指针, 来为MyType对象分配空间, 如果托管堆没有足够空间, 会引起垃圾收集器工作. CLR在分配空间之前,知道所有类型的元数据,所以能知道每个类型的大小, 即占用空间的大小.

In this sample, myType is a local variable. the object instantiated by new operation is stored in managed heap, and the myType local variable is stored in managed stack. The myType local variable on managed stack has a pointer pointing to the address of the object instantiated by new operation. When CLR executes the method, CLR moves the pointer of managed stack to allocate memory for the local variable myType. When CLR executes new operation, CLR checks first whether managed heap has enough space, if enough then do a simple action – move the pointer of managed heap to allocate space for the object of MyType. If managed heap does not have space, this triggers garbage collector to function. CLR knows all the metadata of types, and knows the size of all the types, and then knows how big space the types need.

当CLR完成MyMethod方法的执行时, 托管栈上的myType局部变量被立即删除, 但是托管堆上的MyType对象却不一定马上删除. 这取决于垃圾收集器的触发条件.后面要介绍此触发条件.When CLR finishs execution of MyMethod method, the local variable myType on managed stack is deleted immediately, but the object of MyType on managed heap may not be deleted immediately. This depends on the trigger condition of garbage collector. I will talk about the trigger condition later.

上面我们了解了CLR如何管理托管资源. 下面我们来看垃圾收集器如何寻找不再使用的托管对象,并释放其占用的内存. In previous paragraphs, we learn how CLR manages managed resources. In following paragraphs, we will see how garbage collector find objects no longer needed, and release the memory.

垃圾收集器如何寻找不再使用的托管对象,并释放其占用的内存How garbage collector find objects no longer needed and release memory

前面我们了解了CLR如何管理托管栈上的对象.按照先进后出原则即可比较容易地管理托管栈的内存. 托管堆的管理比托管栈的管理复杂多了.下面所谈都是针对托管堆的管理. In previous paragraphs, we learn how CLR manages the objects on managed stack. It is easy to manage managed stack as long as you utilize the rule “first in last out”. The management of managed heap is much more complicated than the management of managed stack. The following is all about the management of managed heap.

根The root

垃圾收集器寻找不再使用的托管对象时, 其判断依据是当一个对象不再有引用指向它, 就说明此对象是可以释放了. 一些复杂的情况下可以出现一个对象指向第二个对象,第二个对象指向第三个对象,…就象一个链表. 那么, 垃圾收集器从哪里开始查找不再使用的托管对象呢? 以刚才所说的链表为例, 显然是应该从链表的开头开始查找. 那么,在链表开头的是些什么东东呢? The criteria garbage collector uses to judge whether an object is no longer needed is that an object can be released when the object does have any reference. In some complicated cases, it happends that the first object refers to the second object, and the second object points to the third object, etc. It is looking like a chain of single linked nodes. Then the question is : where does the garbage collector begins to find objects no longer needed? For the example of the single linked node chain, we can say it is obvious garbage collector starts from the beginning of the chain. Then the next question is: what are the stuff at the beginning of the chain.

是局部变量, 全局变量, 静态变量, 指向托管堆的CPU寄存器. 在CLR中,它们被称之为根. The answer is : local variables, global variables, static variables, the CPU registers pointing to managed heap. In CLR, they are called “the roots”.

有了开始点, 垃圾收集器接下来怎么做呢? Got the roots, what will garbage collector do next?

创建一个图, 一个描述对象间引用关系的图. Build a graph, which shows the reference relationship among objects.

垃圾收集器首先假定所有在托管堆里面的对象都是不可到达的(或者说没有被引用的,不再需要的), 然后从根上的那些变量开始, 针对每一个根上的变量, 找出其引用的托管堆上的对象, 将找到的对象加入这个图, 然后再沿着这个对象往下找,看看它有没有引用另外一个对象, 有的话,继续将找到的对象加入图中,如果没有的话, 就说明这条链已经找到尾部了. 垃圾收集器就去从根上的另外一个变量开始找, 直到根上的所有变量都找过了, 然后垃圾收集器才停止查找. 值得一提的是, 在查找过程中, 垃圾收集器有些小的优化, 如: 由于对象间的引用关系可能是比较复杂的, 所以有可能找到一个对象, 而此对象已经加入图了, 那么垃圾收集器就不再在此条链上继续查找, 转去其他的链上继续找. 这样对垃圾收集器的性能有所改善.

First garbage collector supposes all the objects in managed heap are not reachable( do not have reference, or no longer needed). Then start from the variables in the roots. For each of the variable in the roots, search the object the variable refers to, and add the found object into the graph, and search again after the found object for next refered object, etc. Check whether the found object has next reference. If has, continue to add the next found object into the graph. If not, it means this is the end of the chain, then stop searching on the chain, continue on next variable in the roots, keep searching on roots, until all the searching are finished. In the searching process, garbage collector has some optimization to improve the performance. Like: Because the reference relationship could be complicated among objects, it is possible to find an object that has been added into the graph, then garbage collector stops searching on the chain, continue to search next chain. This way helps on performance of garbage collection.

垃圾收集器建好这个图之后, 剩下那些没有在这个图中的对象就是不再需要的. 垃圾收集器就可以回收它们占用的空间.After buidling the reference graph among objects, the objects not in the graph are no longer needed objects. Garbage collector could release the memory space occupied by the no longer needed objects.

 

未完待续To be continued…

参考文献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
水平有限, 敬请指正!

请大家尽量用英语评论. 谢谢

从今日到五一, 本人回家陪家人, 评论都无法回复.

时间: 2024-09-23 10:28:32

.net垃圾回收和CLR 4.0对垃圾回收所做的改进之一的相关文章

.net垃圾回收和CLR 4.0对垃圾回收所做的改进之三

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对垃圾回收所做的改进之二 弱引用Weak Reference 弱引用是相对强引用来说的.强引用指的是根有一个指针指向对象.弱引用是通过

.net垃圾回收和CLR 4.0对垃圾回收所做的改进之二

A survey of garbage collection and the changes CLR 4.0 brings in Part 2 - series of what is new in CLR 4.0 接前篇Continue the previous post .net垃圾回收和CLR 4.0对垃圾回收所做的改进之一 CLR4.0所带来的变化仍然没有在这篇,请看下篇. 内存释放和压缩 创建对象引用图之后,垃圾回收器将那些没有在这个图中的对象(即不再需要的对象)释放.释放内存之后, 出

浅谈CLR的内存分配和回收机制

相对于C++程序员来说,C#程序员是非常幸运的,至少我们不需要为内存泄漏(Memory Leak)而头疼,不需要负责内存的分配和回收.但这不意味着我们只需要知道new的语法 就可以了,作为一个严肃的C#程序员,我们应该对此有所了解,有助于我们编写性能更好 的代码. 主要内容: CLR的内存分配机制 CLR的回收机制 一.CLR的内存分配机制 .NET Framework 的垃圾回收器管理应用程序的内存分配和释放.每次使用 new 运算 符创建对象时,运行库都从托管堆为该对象分配内存.只要托管堆中

“正规优化”也可能会促发百度Web2.0反垃圾机制

seo是一种较为流行的网络营销方式,也是网络营销中比较廉价.稳定的一种形式,在众多seo人员看来,seo并非很可靠.并非稳定,因为算法的每次调整可能都会殃及到网站,关键词排名的起伏已在站长看来是一件非常寻常的事.最近百度站长平台发布了百度Web2.0反垃圾攻略,导致很多网站消失在人们的视野中. 百度推出Web2.0反垃圾攻略对seo是否有较大的影响,对于大多数网站来说可能受到的影响不是很大,而一些利用群发外链的网站来说可能受到的伤害会很大,因为当这些外链是百度这次严打的对象;而对于一些利用"正规

对百度发布的web2.0反垃圾攻略所感

你是否有这样的感受,当你在百度搜索一个东西或是一个问题的时候,返回的结果时常都不让人满意,有的都是在打广告,有的是文不对题,更有的是一个跳转链接.现在的网络上真的是充斥着太多的垃圾. 对于百度发布的web2.0反垃圾攻略旨在打击那些不断制造垃圾信息的seo,虽然我也是做seo的,这样做对我们以后的工作也会增加一定的难度,但是我对百度的这一做法还是深表赞同的. 接触这个行业也有一两年了,我就有一个深深的感觉我每天都在制造垃圾,真的,又是迫不得已,因为别人都在这么做,你不做你就会落后,就像现在的小孩

百度web2.0反垃圾攻略,垃圾站将会死亡

5月2日百度发布了<web2.0反垃圾攻略>表明百度将会加大打击垃圾站的力度.4月份很多网站的收录大幅减少,A5这些大站也不例外,众多博客站被降权,还有淘宝客网站也受到很大影响.目前大部分网站的收录已恢复正常,被删的收录页面也陆续放出来了.4月份以来百度算法的不断更新也暗示着百度算法会有重大调整. 群发链接无效.百度在<web2.0反垃圾攻略>中列举了众多群发外链的例子.比如我们站长最常做的博客外链群发,论坛外链群发,分类外链群发.百度在未来会通过不断更新算法让垃圾外链消失在百度搜

百度Web2.0反垃圾攻略打击垃圾信息页面

大家好,我是木子成舟.SEO行业中最怕的就是搜索引擎算法调整,因为一旦算法调整我们就需要针对搜索引擎的算法调整及时的做出转变,然后搜索引擎的算法调整又是真正利用SEO技术做好网站推广工作的福音,因为算法的调整绝对是针对搜索结果质量的调整,针对SEO作弊手法的针对制约,只要我们充分运用好白帽SEO手段,不制造垃圾信息页面,搜索引擎的调整只会利于我们正规SEO的工作. 不知道是不是为了顺应潮流,还是学习跟风,百度在谷歌推出Panda算法和企鹅算法之后,也推出了自己的一套打击垃圾信息页面的算法,主要是

CLR 4.0中的新内容:状态错乱异常

状态错乱异常 有人叫它超级异常. 指的是未捕获异常, 打乱了程序的状态, 引起程序崩溃, 或者导致不想看到的程序行为, 如同神经错乱. CLR4.0针对未捕获异常做了一种可配置的处理机制. 请看下面的程序. 在CLR2.0里, 这个catch (Exception ex) 将所有可能发生的异常都捕获. 在CLR4.0里, 默认情况下这个超级catch不会生效, 一旦出现异常就会导致程序停止. class Program { static void Main(string[] args) { Sa

IIS6.0应用程序池回收设置分析_win服务器

问题如下: 1.网页上显示 您试图在此 Web 服务器上访问的 Web 应用程序当前不可用.请点击 Web 浏览器中的"刷新"按钮重试您的请求. 管理员注意事项: 详述此特定请求失败原因的错误信息可在 Web 服务器的系统事件日志中找到.请检查此日志项以查明导致该错误发生的原因. 2.windows事件查看器-应用程序Log The state server has closed an expired TCP/IP connection. The IP address of the c