`
mmdev
  • 浏览: 12926209 次
  • 性别: Icon_minigender_1
  • 来自: 大连
文章分类
社区版块
存档分类
最新评论

设计.Net Compact Framework CLR(3)

阅读更多
第三章:GC Heap管理
这是《设计.Net Compact Framework CLR》的第三部分。在前面两章中,我们讨论了CLR如何管理内存和JIT编译器的基本设计原则。
Part I, Overview and Background
Part II, Jit Compiler Design Considerations
这一章我们主要讨论垃圾收集设计中如何管理GC heap的问题。
---------
讨论.NET平台如何管理内存,垃圾收集肯定是第一个被提及的话题。不必惊讶,Compact Framework的垃圾收集和桌面版本有很多地方不同,原因是运行环境的不同。就像Compact Framework CLR中的其他大部分子系统一样,垃圾收集被设计成,在设备可用内存较低时,释放所有能够释放的内存。
对更高层次,GC提供了两个基本功能:分配内存保存引用类型的实例,在这些实例不再使用时收集他们。
Allocating Reference Types
通过第一章的讨论,我们知道GC heap存在于进程独有的32M虚拟地址空间中。和JIT堆一样,GC heap开始时很小,随着增长需要更多的空间。然而,比较JIT堆,GC heap的增长有两个重要的不同:GC heap以一个固定的增量增长,另外,它不会增长到很大。

GC Heap的增量通常是6K。当一个新的64K“内存段”被创建时,内存分配将从该段中被分配,直到没有足够的空间,然后一个新的“内存段”将被创建。Compact Framework GC使用标准Win32 API VirtualAlloc来分配新的内存段。分配一个内存段是很快的。在.NET Compact Framework 2.0的性能测试显示,每秒可以分配750万个小型引用类型的实例。分配器之所以如此高效,是因为它使用了简单的算法。在GC堆中用一个指针指向下一个有效空间。当分配一个新实例的空间时,分配器简单地将指针移动该对象所需要的字节数就可以了,如图4所示:

Figure 4
分配一个新的引用类型只是简单地移动“next object”指针
GC heap默认的增量值是64K,在分配大于64K的对象时,分配器将会以比较大的增量来增加Heap的尺寸。例如,如果一个程序尝试创建一个70K的对象,分配器将创建一个新的70K的内存段来存储这个大对象。

Gc Heap会像我们描述得这样一直增加,直到达到1MB。这时一个垃圾回收机制将被启动(更多地回收将在以后出现)。在这以后,GC Heap也许会继续增长,但是从上一次回收后,只要分配了1MB的对象,垃圾回收就会被启动。
Collecting Reference Types
现在我们已经了解GC Heap是如何增长的,让我们来看看它是如何收缩的。此外,在内存压力下减少GC heap尺寸的能力是帮助应用程序更好地运行在内存受限设备上的关键。在这一节中,我们将考虑那些原因会触发一次垃圾回收和内存何时被释放并被返回给操作系统。

有一些原因会触发垃圾回收机制。这些原因中的一个就是分配了1MB的托管对象。其他原因包括分配资源失败,例如,无法分配更多的内存,创建更多的Windows句柄等。请查看An Overview of the .Net Compact Framework Garbage Collector中对这些引发收回原因的详细讨论。
当GC发生时,内存不是每次都会被释放并返回给操作系统的。为了理解从操作系统角度来看内存何时被释放,让我们来看一下当垃圾回收运行时到底发生了什么?
Unreferenced Objects
在每次垃圾回收的过程中,GC会检索整个Heap以发现哪些对象不再被引用。这些不再使用对象的内存将被释放回GC Heap,使GC heap有更多可用空间。在释放不再引用的类型后,一些64K的内存段将有可能是完全空着的。如果内存段是完全空的并且GC仍然有1MB以上的分配空间,空的64K内存段将通过调用VirtualFree被归还给操作系统。除了完整GC(原文为”full” GC,将在下面讨论)外,收集器将会保持总数1MB的64K内存段的缓存,即使其中的一些内存段是空的。通过缓存代码段的方式,我们通过减少调用VirtualAlloc和VirtualFree的次数来改善性能。
Compacting the GC Heap
在垃圾回收的过程中,GC将随意地压缩堆。当一个堆充满碎片时,收集器将通过将所有活动对象移动到一起的方式,来“压实”整个堆。压实堆的主要目的是产生大量的有效内存块,以分配更多的对象。图5表现了GC Heap中的内容在压缩前后的状态。

Figure 5
The contents of a sample GC heap before and after compaction
通过”简单”对象回收,GC将归还1MB内存段缓存之外的空64K内存段给操作系统。
A "Full" GC
在正常的事态发展下,GC将按照下面描述的方式来工作:在每次分配1MB之后,周期性的垃圾回收将被启动;如果Heap充满碎片,它将被压缩;如果收集器有1MB的缓存,多余的空内存段将被返还给操作系统。
事实上,在这三个设定之外,为了获取更多的可用内存,还会使用哪些更激烈地做法。这些做法和发生的时机密切相关,就像第二章中JIT在这些时候减小它的Heap尺寸:当分配内存或其他资源失败时发生,当一个应用程序被切换到后台时,或者当应用程序接收到操作系统的WM_HIBERNATE消息时。在这些时候,GC将不再保持在1MB的内存段缓存上。(译注:原文为the GC will hot hold onto its 1MB segment cache.严重怀疑是the GC will not hold onto its 1MB segment cache.否则意思不通,故改之)它将回收所有的不在引用的对象,压缩堆,并且释放所有可以释放的内存。
Pulling it All Together
现在我们已经了解了GC如何分配和释放内存,让我们看一下GC heap的尺寸在应用程序的生命周期中的变化。

Figure 6
The size of the GC heap over the lifetime of an application.

图6跟踪了两部分的数据,黄色线表示在应用程序的生命周期中,垃圾收集被请求分配的累计byte数。该数将持续增长,不会跳跃,就像应用程序持续分配新对象。

图6中的蓝色线表示每个时间GC heap的尺寸。有几个时间点值得注意。首先,当应用程序开始并持续运行时,我们看到GC heap的尺寸的增长和前面所见是一致的。图中的每一步和新创建的64K GC段是一致的。第二,我们可以看到有时蓝色线水平偏离。就像你在前边关于分配和回收算法的讨论中所了解的那样,在1MB的时候heap尺寸变成水平。接下来,你可以看到heap尺寸戏剧性地下降。下降的发生在我将应用程序切换到后台时。在应用程序切换到前台后,我们开始看到heap再次以64K开始增长。

这个系列现在覆盖了.Net Compact Framework如何管理内存的基础,和构建JIT编译器和垃圾回收时的设计决定。在我的下一篇中,我们将讨论在内存受限设备中,CLR class loader如何运行得更有效率。
This posting is provided "AS IS" with no warranties, and confers no rights.

Aawolf: Steven老兄最近好象对这个系列文章不感兴趣了,没有再更新。不过他的文章还是很有意思的,不多的文字就解释了一些隐藏在背后的运行机制。期待他的下一篇。
分享到:
评论

相关推荐

    .NET Framework 4.0 常用类库参考手册 [微软官方 MSDN]

    .NET Framework 4.0 常用类库参考手册 [微软官方 MSDN] MSDN Library - .NET Framework 4.0 - 命名空间 (节选版) 制作成了chm格式,方便离线状态下学习! ======================================= 原文地址:...

    强大的.net调试工具CLRProfiler

    CLR rofiler允许你查看进程的托管堆并且研究垃圾回收器的特性,使用该工具的不同视图,你可以得到你的应用程序有关执行,分配,已经内存消耗的情况。

    .NET CLR via C#(第4版) 最新完整版 高清文字版

    本书针对clr、C#5.0和.net framework 4.5进行深入、全面的探讨,并结合实例介绍了如何利用它们进行设计、开发和调试。 本书深入、全面探讨.NET Framework、CRL和多核编程,广泛讨论FrameworkClassLibrary(FCL)核心...

    Pro .NET Framework with the Base Class Library Pdf

    The author first gives an introduction to the .NET Framework and describes the architectural and engineering resources required when implementing the .NET Framework on any platform. Next, you will ...

    Vc.net/CLR UDP通讯

    Vc.net/CLR UDP通讯

    Vc.net/CLR TCP通讯客户端

    Vc.net/CLR TCP通讯客户端

    CLR via C# Applied Microsoft.NET Framework Programming, second edition

    .net framework book, it's the 2nd edition which shows you how CLR works and what you should be clear on developping with .net framework

    Infragistics NetAdvantage for ASP.NET 2007 Vol.3 CLR2 Source

    Infragistics NetAdvantage 2007 Vol.3 用于.NET framework 2.0 ASP.NET的源代码 版本号是v7.3.20073.1043

    .NET Framework中CTS、CLS、CLR

    关于.NET Framework中CTS、CLS、CLR的详细说明

    微软.NET CLR统计分析器源码

    微软.NET CLR统计分析器,可以统计内存使用情况,统计各种信息,让人了解CLR内部工作情况,深入了解CLR

    你必须知道的.NET

    第3部分论述.NET Framework框架的方方面面,详细分析了.NET框架的所有重点、难点和疑点内容,对框架类库的全貌进行了必要的专题性探讨;第4部分重点介绍了.NET泛型和安全性的相关知识和本质解密;第5部分对.NET 3.0/...

    C# .NET 课件 最好的

    C#.net.NET Framework由框架类库(FCL)和公共语言运行时(CLR)两个主要组件构成 CLR是管理用户代码执行的现代运行时环境,它提供JIT 编译、内存管理、异常管理和调试等方面的服务 CTS定义声明、定义和管理所有...

    中科大.NET课件(讲解CLR)

    中科大.NET课件(讲解CLR)通用语言运行时

    Infragistics NetAdvantage for .NET 2008 Vol.3 CLR 3.5 KeyGen

    TInfragistics NetAdvantage for .NET 2008 Vol.3 LR 3.5 KeyGen

    .net教程 .net教程 .net教程 .net教程

    第3部分论述.NET Framework框架的方方面面,详细分析了.NET框架的所有重点、难点和疑点内容,对框架类库的全貌进行了必要的专题性探讨;第4部分重点介绍了.NET泛型和安全性的相关知识和本质解密;第5部分对.NET 3.0/...

    .NET CLR via C#(第4版)中文 part3(3-5)

    中文第四版 ...CLR是.NET Framework的核心,《CLR via C#》使你穿云破雾,直抵核心,以窥堂奥。知其然,只能说是才入门,只有知其所以然,“登堂入室”,才能达至“不为浮云遮望眼,只缘身在此山中”的境界。

    你必须知道的.net

    第3部分论述.NET Framework框架的方方面面,详细分析了.NET框架的所有重点、难点和疑点内容,对框架类库的全貌进行了必要的专题性探讨;第4部分重点介绍了.NET泛型和安全性的相关知识和本质解密;第5部分对.NET 3.0/...

    ASP.NET程序设计教程 崔连和 课后习题及答案

    3.计算机中安装( .NET Framework )以后,系统就可以运行任何.NET 语言编写的软件。 4..NET Framework 由两部分组成:( 框架类库 )和( 公共语言运行库 )。 5.CLR 是指( 公共语言运行库 ),其功能是负责...

    Microsoft .NET Framework 4

    .NET Framework 是由 Microsoft 开发的一种全面且一致的编程模型,用于生成具有视觉震撼力的用户体验、无缝的安全通信和对一系列业务流程进行建模的能力的应用程序。 .NET Framework 4 将与旧的 Framework 版本并行...

    .net Framework 试卷

    .net试卷,题型有填空、问答、程序填空、看程序写结果,考试内容涉及CLR相关概念、编程、安全机制等

Global site tag (gtag.js) - Google Analytics