ImageVerifierCode 换一换
格式:DOCX , 页数:22 ,大小:501.84KB ,
资源ID:6208466      下载积分:3 金币
快捷下载
登录下载
邮箱/手机:
温馨提示:
快捷下载时,用户名和密码都是您填写的邮箱或者手机号,方便查询和重复下载(系统自动生成)。 如填写123,账号就是123,密码也是123。
特别说明:
请自助下载,系统不会自动发送文件的哦; 如果您已付费,想二次下载,请登录后访问:我的下载记录
支付方式: 支付宝    微信支付   
验证码:   换一换

加入VIP,免费下载
 

温馨提示:由于个人手机设置不同,如果发现不能下载,请复制以下地址【https://www.bdocx.com/down/6208466.html】到电脑端继续下载(重复下载不扣费)。

已注册用户请登录:
账号:
密码:
验证码:   换一换
  忘记密码?
三方登录: 微信登录   QQ登录  

下载须知

1: 本站所有资源如无特殊说明,都需要本地电脑安装OFFICE2007和PDF阅读器。
2: 试题试卷类文档,如果标题没有明确说明有答案则都视为没有答案,请知晓。
3: 文件的所有权益归上传用户所有。
4. 未经权益所有人同意不得将文件中的内容挪作商业或盈利用途。
5. 本站仅提供交流平台,并不能对任何下载内容负责。
6. 下载文件中如有侵权或不适当内容,请与我们联系,我们立即纠正。
7. 本站不保证下载资源的准确性、安全性和完整性, 同时也不承担用户因使用这些下载资源对自己和他人造成任何形式的伤害或损失。

版权提示 | 免责声明

本文(NET Framework 垃圾回收 35 Version.docx)为本站会员(b****5)主动上传,冰豆网仅提供信息存储空间,仅对用户上传内容的表现方式做保护处理,对上载内容本身不做任何修改或编辑。 若此文所含内容侵犯了您的版权或隐私,请立即通知冰豆网(发送邮件至service@bdocx.com或直接QQ联系客服),我们立即给予删除!

NET Framework 垃圾回收 35 Version.docx

1、NET Framework 垃圾回收 35 Version 垃圾回收 Framework 3.5 versionAuthor: Jerry Huang目录1. 垃圾回收概述2. Finalize方法和析构函数3. 弱引用4. 被动回收5. 滞后时间模式6. 针对共享WEB宿主优化7. 垃圾回收通知8. 清理非托管资源9. 参考 C# 析构函数10. 参考 WeakReference类11.参考 垃圾回收内部原理垃圾回收.NET Framework 的垃圾回收器管理应用程序的内存分配和释放。每次您使用 new 运算符创建对象时,运行时都从托管堆为该对象分配内存。只要托管堆中有地址空间可用,运行时

2、就会继续为新对象分配空间。但是,内存不是无限大的。最终,垃圾回收器必须执行回收以释放一些内存。垃圾回收器优化引擎根据正在进行的分配情况确定执行回收的最佳时间。当垃圾回收器执行回收时,它检查托管堆中不再被应用程序使用的对象并执行必要的操作来回收它们占用的内存。 本节介绍了垃圾回收器如何自动管理应用程序中托管对象的内存分配和释放。除此之外,本节还介绍了推荐的设计模式,以用来正确地清理应用程序创建的任何非托管资源。 说明:在 .NET Framework 1.0 版中,公共语言运行时 (CLR) 具有一个用于大型对象堆的独立内存管理器。在某些情况下,该内存管理器不将未使用的内存返回给操作系统,在少数

3、情况下,它还会使该内存不能垃圾回收。这样会由于虚拟地址空间碎片而导致内存分配失败。在 .NET Framework 1.1 和 2.0 版中,大型对象堆由称为堆片段的连续内存区域组成,这些区域完全对齐以使虚拟内存碎片减到最少。在垃圾回收过程中,从大型对象中回收的空间被合并起来并置于自由列表中。只包含自由列表项的堆片段被释放,内存被返回给操作系统。对大型对象堆所做的这些更改有效消除了由这种形式的虚拟地址空间碎片导致的内存分配故障。重要说明:在内存大于 2GB 的服务器中,可能需要在 boot.ini 文件中指定 /3GB 开关,以避免当内存仍可供系统使用时出现明显的内存不足问题。本节内容Fina

4、lize 方法和析构函数介绍 Finalize 方法和析构函数如何允许对象在垃圾回收器自动回收对象的内存之前执行必要的清理操作。 弱引用介绍允许应用程序访问对象,同时也允许垃圾回收器收集该对象的功能。 被动回收介绍如何立即或在下一最佳时间回收对象。 滞后时间模式介绍可确定垃圾回收侵入性的模式。 针对共享 Web 宿主优化介绍在通过承载若干个小型网站共享的服务器上如何优化垃圾回收。 垃圾回收通知介绍如何确定完整垃圾回收何时即将发生以及何时完成。 清理非托管资源介绍推荐的清理非托管资源的设计模式。 Finalize 方法和析构函数对于您的应用程序创建的大多数对象,可以依靠 .NET Framewo

5、rk 的垃圾回收器隐式地执行所有必要的内存管理任务。但是,在您创建封装非托管资源的对象时,当您在应用程序中使用完这些非托管资源之后,您必须显式地释放它们。最常见的一类非托管资源就是包装操作系统资源的对象,例如文件、窗口或网络连接。虽然垃圾回收器可以跟踪封装非托管资源的对象的生存期,但它不了解具体如何清理这些资源。对于这些类型的对象,.NET Framework 提供 Object.Finalize 方法,它允许对象在垃圾回收器回收该对象使用的内存时适当清理其非托管资源。默认情况下,Finalize 方法不执行任何操作。如果您要让垃圾回收器在回收对象的内存之前对对象执行清理操作,您必须在类中重写

6、 Finalize 方法。说明:若要在 C# 中实现 Finalize 方法,您必须使用析构函数语法。在 .NET Framework 2.0 版中,Visual C+ 为实现 Finalize 方法提供了自己的语法,详见Destructors and Finalizers in Visual C+中的介绍。在 .NET Framework 1.0 版和 1.1 版中,Visual C+ 与 C# 一样,也对 Finalize 方法使用析构函数语法。垃圾回收器使用名为“终止队列”的内部结构跟踪具有 Finalize 方法的对象。每次您的应用程序创建具有 Finalize 方法的对象时,垃圾回收

7、器都在终止队列中放置一个指向该对象的项。托管堆中所有需要在垃圾回收器回收其内存之前调用它们的终止代码的对象都在终止队列中含有项。说明:为 GC.KeepAlive 方法提供的代码示例演示攻击性垃圾回收如何会导致终结器在已回收的对象的成员仍在执行时运行,以及如何使用 KeepAlive 方法来阻止这种情况的发生。Finalize 方法不应引发异常,因为应用程序无法处理这些异常,而且这些异常会导致应用程序终止。实现 Finalize 方法或析构函数对性能可能会有负面影响,因此应避免不必要地使用它们。用 Finalize 方法回收对象使用的内存需要至少两次垃圾回收。当垃圾回收器执行回收时,它只回收没

8、有终结器的不可访问对象的内存。这时,它不能回收具有终结器的不可访问对象。它改为将这些对象的项从终止队列中移除并将它们放置在标为准备终止的对象列表中。该列表中的项指向托管堆中准备被调用其终止代码的对象。垃圾回收器为此列表中的对象调用 Finalize 方法,然后,将这些项从列表中移除。后来的垃圾回收将确定终止的对象确实是垃圾,因为标为准备终止对象的列表中的项不再指向它们。在后来的垃圾回收中,实际上回收了对象的内存。示例:对象A:没有终结器(Finalize)的不可访问对象。对象B:有终结器(Finalize)的不可访问对象。弱引用如果应用程序的代码可以访问一个正由该程序使用的对象,垃圾回收器就不

9、能收集该对象,那么,就认为应用程序对该对象具有强引用。 弱引用允许应用程序访问对象,同时也允许垃圾回收器收集相应的对象。如果不存在强引用,则弱引用的有限期只限于收集对象前的一个不确定的时间段。使用弱引用时,应用程序仍可对该对象进行强引用,这样做可防止该对象被收集。但始终存在这样的风险:垃圾回收器在重新建立强引用之前先处理该对象。弱引用特别适合以下对象:占用大量内存,但通过垃圾回收功能回收以后很容易重新创建。假设 Windows 窗体应用程序中的一个树视图向用户显示了复杂的选项层次结构。如果基础数据量很大,则用户使用应用程序中的其他部分时,在内存中保留该树会导致效率低下。 当用户切换到应用程序的

10、其他部分时,可使用 WeakReference 类来创建对该树的弱引用,并销毁所有强引用。当用户切换回该树时,应用程序会尝试获得对该树的强引用,如果得到,就不必重新构造该树。要对某个对象建立弱引用,请使用要跟踪的对象的实例创建一个 WeakReference。然后将 Target 属性设置为该对象,将该对象设置为 null。有关代码示例,请参见类库中的 WeakReference。短弱引用和长弱引用 可创建短弱引用或长弱引用: 短垃圾回收功能回收对象后,短弱引用的目标会变为 null。弱引用本身是托管对象,和任何其他托管对象一样需要经过垃圾回收。 短弱引用是 WeakReference 的默认

11、构造函数。 长调用对象的 Finalize 方法后,会保留长弱引用。这样,您就可以重新创建该对象,但该对象仍保持不可预知的状态。要使用长引用,请在 WeakReference 构造函数中指定 true。如果对象的类型没有 Finalize 方法,则会应用短弱引用功能,该弱引用只在目标被收集之前有效,运行终结器之后可以随时收集目标。要建立强引用并重新使用该对象,请将 WeakReference 的 Target 属性强制转换为该对象的类型。如果 Target 属性返回 null,则表示对象已被收集;否则,您可继续使用该对象,因为应用程序已重新获得了对它的强引用。 使用弱引用的准则 仅在必要时使用

12、长弱引用,因为在终止后对象的状态是不可预知的。 避免对小对象使用弱引用,因为指针本身可能和对象一样大,或者比对象还大。 不应将弱引用作为内存管理问题的自动解决方案,而应开发一个有效的缓存策略来处理应用程序的对象。被动回收在大多数情况下,垃圾回收器可以确定执行回收的最佳时间,应让其独立运行。在某些不常发生的情况下,强制回收可以提高应用程序的性能。在这些情况下,可使用 Collect 方法强制垃圾回收,以引发垃圾回收。当应用程序代码中某个确定的点上使用的内存量大量减少时,请使用 Collect 方法。例如,如果应用程序使用包含若干个控件的复杂对话框,则在对话框关闭时调用 Collect 可能会通过

13、立即回收内存来提高性能。务必确保应用程序不会过于频繁地引发垃圾回收,否则当垃圾回收器无效率地尝试回收对象时,可能会使性能降低。Optimized 模式使垃圾回收器可以根据收集是否有效率来确定是否进行回收。GC 回收模式 可以使用 GC.Collect 方法重载,它使用 GCCollectionMode 值指定强制回收的行为,如下表所述。成员说明Default使用指定的设置作为正在运行的 .NET Framework 版本的默认垃圾回收配置。Forced强制立即执行垃圾回收。这等效于调用 GC.Collect()。Optimized使垃圾回收器可以确定当前时间是否是回收对象的最佳时间。垃圾回收器

14、可能判定收集效率不够高,因此收集不合理,在这种情况下将返回而不回收对象。滞后时间模式若要回收对象,垃圾回收器必须停止应用程序的所有正在执行的线程。在某些情况下,例如当应用程序检索数据或者显示内容时,完整垃圾回收可能会在关键时刻进行,而且可能会影响性能。可以通过将 LatencyMode 属性设置为 GCLatencyMode 值之一来调整垃圾回收器的侵入性。 滞后时间指的是垃圾回收器侵入应用程序的时间。在低滞后时间期间,垃圾回收器在回收对象时较保守且侵入性较弱。第 2 代回收不常发生,这使得应用程序工作集随着时间而增长。因此,建议您在需要 LowLatency 模式时仅在短时间内使用该模式。否

15、则,如果系统处于内存压力下,垃圾回收器将触发一次回收,这样会暂时暂停应用程序并中断对时间要求很急的操作。 低滞后时间模式应当用于以下应用程序:包含运行时间较短的代码块,而且必须在运行时中断最少的情况下运行。虽然 LowLatency 模式设计用于存在某些时间限制的情况中,但它并不是针对存在严格实时限制的情况的解决方案。 下表列出了 GCLatencyMode 值适用的应用程序方案。滞后时间模式 应用程序方案 Batch 适用于没有 UI 或服务器端操作的应用程序。 Interactive 适用于多数有 UI 的应用程序。 LowLatency 适用于在垃圾回收器的中断可以中断时具有时效性短期操

16、作的应用程序。例如,执行动画呈现或数据采集功能的应用程序。 默认垃圾回收模式 如果未指定 LatencyMode 属性,则默认模式为并发工作站垃圾回收。该模式取决于两个运行时配置设置的值: 如果启用,则此设置指定公共语言运行时在单独的线程上运行工作站垃圾回收以支持并发操作。默认情况下会启用此设置。 如果启用,则此设置指定公共语言运行时运行服务器垃圾回收;如果未启用,则运行工作站垃圾回收。只能在具有两个或更多处理器的计算机上启用服务器垃圾回收。默认情况下不启用此选项。 如果启用此设置,则自动禁用 。 GCLatencyMode 的默认值如下: 在启用 且禁用 时为 Interactive。 在禁

17、用 时或同时启用 和 时为 Batch。说明:如果应用程序在实现 Intel Itanium 体系结构的 64 位系统(以前称为 IA-64)上运行 WOW64 x86 仿真程序,则在这些应用程序中不支持并发垃圾回收。有关在 64 位 Windows 系统上使用 WOW64 的更多信息,请参见 Running 32-bit Applications(运行 32 位应用程序)。低滞后时间使用准则 使用 LowLatency 模式时,请考虑下列准则: 使处于低滞后时间模式的时间尽可能短。 在低滞后时间期间,避免分配大量内存。可能会出现内存不足通知,因为垃圾回收所回收的对象较少。 在低滞后时间模式下

18、,最大限度地减少所进行的分配次数,特别是向大型对象堆和固定对象所做的分配。 请注意可能正在进行分配的线程。由于 LatencyMode 属性设置是针对整个进程的,因此也许会在任何可能正在分配的线程上产生 OutOfMemoryException。 将低滞后时间代码包装在受约束的执行区域中(有关更多信息,请参见受约束的执行区域)。 可以通过调用 GC.Collect(Int32, GCCollectionMode) 方法在低滞后时间期间强制进行第 2 代回收。 针对共享Web宿主优化如果您是通过承载若干个小型网站来共享的服务器的管理员,则可向 .NET Framework 目录下 Aspnet.

19、config 文件中的 runtime 节点中添加以下 gcTrimCommitOnLowMemory 设置,以优化性能并增加网站容量:说明:建议只将此设置用于共享 Web 宿主的情况。由于垃圾回收器会保留内存以供将来分配,因此其提交空间可能多于真正需要的空间。可以减小此空间,以适应系统内存负载较大的情况。减小此提交空间可以提高性能并扩展容量,以承载更多站点。启用 gcTrimCommitOnLowMemory 设置后,垃圾回收器将评估系统内存负载,并在负载达到 90% 时进入修整模式。垃圾回收器将一直处于修整模式,直到负载下降到 85% 以下。当情况允许时,垃圾回收器可以确定 gcTrimC

20、ommitOnLowMemory 设置对当前应用程序没有帮助,并将其忽略。 示例 下面的 XML 片段演示如何启用 gcTrimCommitOnLowMemory 设置。椭圆指示将在 runtime 节点中的其他设置。 . . . . . .垃圾回收通知公共语言运行时执行的完整垃圾回收有时可能会对性能产生负面影响。对于处理大量请求的服务器而言,这个问题尤为突出;在这种情况下,长时间的垃圾回收可能会导致请求超时。若要防止在重要时间段发生完整垃圾回收,可以让系统通知您即将发生完整垃圾回收,然后您可以采取措施将工作负荷重定向到其他服务器实例。您也可以在当前服务器实例不需要处理请求时自己引发回收。 说

21、明:仅当禁用并发垃圾回收时才能使用此功能。默认情况下会启用并发垃圾回收,除非您在宿主环境中运行应用程序且宿主已为您更改了该配置。在使用服务器垃圾回收时,并发垃圾回收不可用。此功能不支持并发垃圾回收,原因是在进行并发垃圾回收期间允许进行内存分配。有关如何禁用并发垃圾回收的信息,请参见 运行时设置。有关垃圾回收的更多信息请参照这里清理非托管资源通过将对象的范围限制为 protected,您可以防止应用程序用户直接调用对象的 Finalize 方法。除此之外,我们强烈建议您不要直接从应用程序代码中调用非基类的类的 Finalize 方法。为适当释放非托管资源,建议您实现公共的 Dispose 或 C

22、lose 方法,这两个方法可为对象执行必要的清理代码操作。IDisposable 接口为实现接口的资源类提供 Dispose 方法。因为 Dispose 方法是公共的,所以应用程序用户可以直接调用该方法来释放非托管资源占用的内存。在正确实现 Dispose 方法时,Finalize 方法在未能调用 Dispose 方法的情况下充当防护措施来清理资源。有关正确实现的更多信息,请参见 实现 Dispose 方法。 本节内容 实现 Dispose 方法描述用于释放非托管资源的 Dispose 方法的实现。 重写 Finalize 方法描述 Finalize 和 Dispose 方法的合作方式。 C#

23、 中的析构函数语法描述 Finalize 方法在 C# 中的等效方法。 使用封装资源的对象描述确保 Dispose 方法得到调用的方式,例如 C# using 语句(在 Visual Basic 中为 Using)。实现 Dispose 方法释放对象的模式(称为释放模式)对对象的生存期进行规定。类型的 Dispose 方法应释放它拥有的所有资源。它还应该通过调用其父类型的 Dispose 方法释放其基类型拥有的所有资源。父类型的 Dispose 方法应该释放它拥有的所有资源,进而调用其父类型的 Dispose 方法,从而在整个基类型层次结构中传播此模式。若要帮助确保始终正确地清理资源,Disp

24、ose 方法应该可以多次调用而不引发异常。对只使用托管资源的类型(如数组)实现 Dispose 方法并不能提高性能,原因是这些类型由垃圾回收器自动回收。应主要对使用本机资源的托管对象和向 .NET Framework 公开的 COM 对象使用 Dispose 方法。使用本机资源的托管对象(如 FileStream 类)实现 IDisposable 接口。重要说明:C+ 程序员不应该使用本主题。而应参见 Destructors and Finalizers in Visual C+。在 .NET Framework 2.0 版中,C+ 编译器为实现资源的确定性处置提供支持,并且不允许直接实现 D

25、ispose 方法。Dispose 方法应为它要释放的对象调用 SuppressFinalize 方法。如果对象当前在终止队列中,则 SuppressFinalize 会阻止调用其 Finalize 方法。请记住,执行 Finalize 方法会降低性能。如果 Dispose 方法已完成清理对象的工作,垃圾回收器就不必调用对象的 Finalize 方法。为 GC.KeepAlive 方法提供的代码示例演示了强行垃圾回收如何在回收对象的成员仍在执行时引起终结器运行。在较长的 Dispose 方法末尾最好调用 KeepAlive 方法。参考代码 - clsDispose.vb重写 Finalize

26、方法Finalize 方法在未能调用 Dispose 方法的情况下充当防护措施来清理资源。您应该只实现 Finalize 方法来清理非托管资源。您不应该对托管对象实现 Finalize 方法,因为垃圾回收器会自动清理托管资源。默认情况下,Object.Finalize 方法不进行任何操作。如果要让垃圾回收器在回收对象的内存之前对对象执行清理操作,您必须在类中重写此方法。说明:您无法在 C# 或 C+ 编程语言中重写 Finalize 方法。在 C# 中可使用析构函数语法实现 Finalize 方法。在 .NET Framework 2.0 版中,C+ 为实现 Finalize 方法提供了自己的

27、语法,如 Destructors and Finalizers in Visual C+ 中所述。在早期版本中,C+ 与 C# 一样也使用析构函数语法来实现 Finalize 方法。Object.Finalize 方法的范围是受保护的。当在类中重写该方法时,您应该保持这个有限的范围。通过保护 Finalize 方法,您可以防止应用程序的用户直接调用对象的 Finalize 方法。对象的 Finalize 方法应该释放该对象保留的所有资源。它还应该调用该对象基类的 Finalize 方法。对象的 Finalize 方法不应对任何非其基类的对象调用方法。这是因为被调用的其他对象可能和调用对象在同一

28、时间被回收,例如公共语言运行库关闭这种情况。如果您允许任何异常避开 Finalize 方法,系统将认为方法返回,并继续调用其他对象的 Finalize 方法。C# 中的析构函数语法您无法从 C# 或 C+ 编程语言中调用或重写 Object.Finalize 方法。C# 将析构函数用作编写终止代码的机制,如 析构函数(C# 编程指南) 中所述。在 C+ 中,析构函数语法用于实现 Dispose 方法。C+ 为实现 Finalize 方法提供了自己的语法,如 Destructors and Finalizers in Visual C+ 中所述。说明:在 .NET Framework 2.0 版

29、之前,C+ 与 C# 一样也使用析构函数用法来实现 Finalize 方法,当时没有特殊语法来实现 Dispose 方法。若要编译使用早期语法的 C+ 代码,请使用 /clr:oldSyntax 编译器选项。尽管看起来相似,但 C# 和 C+ 析构函数的语义与未托管 C+ 析构函数的语义并不相同。托管代码不支持任何与 C+ 析构函数语义相似的语义。使用封装资源的对象如果您要编写代码,而该代码使用一个封装资源的对象,您应该确保在使用完该对象时调用该对象的 Dispose 方法。要做到这一点,可以使用 C# 的 using 语句,或使用其他面向公共语言运行库的语言来实现 try/finally 块

30、。C# 的 Using 语句 C# 编程语言的 using 语句通过简化必须编写以便创建和清理对象的代码,使得对 Dispose 方法的调用更加自动化。using 语句获得一个或多个资源,执行您指定的语句,然后处置对象。请注意,using 语句只适用于这样的对象:这些对象的生存期不超过在其中构建这些对象的方法。下面的代码示例将创建并清理 ResourceWrapper 类的实例,如 C# 示例实现 Dispose 方法中所示。Class myApp public static void Main() using (ResourceWrapper r1 = new ResourceWrapper() / Do something with the object. r1.DoSomething(); 以上合并了 using 语句的代码与下面的代码等效。Class myApp

copyright@ 2008-2022 冰豆网网站版权所有

经营许可证编号:鄂ICP备2022015515号-1