.NET中的垃圾回收(下)

AI权益加码!Claude Code、Cursor等20+工具免费用! 购周边限时加赠Coding Plan Lite,畅享主流AI工具!学习进阶更高效! 阅读详情

垃圾回收性能的优化

l         弱引用(WeakReference

l         代(Generations

 

弱引用(WeakReference

       弱引用(WeakReference)是提高性能的一种方式,用于减少托管堆中大对象的压力。

      

       当一个根指向一个对象时,它被称为这个对象的一个强引用并且这个对象不能被回收,因为应用程序能遍历到这个对象。

 

       当一个对象有一个指向它的弱引用(WeakReference)时,基本上是指如果有内存请求并且GC启动时,这个对象可以被回收,当应用程序再次尝试去访问这个对象时,访问将会失败。另一方面,为了能访问一个被弱引用(WeakReference)的对象,应用程序必须获得一个对这个对象的强引用。如果应用程序在垃圾回收器回收这个对象之前获得了它的强引用,GC将不能回收这个对象,因为有这个对象的强引用存在。

 

       托管堆包含两个管理弱引用(WeakReference)的内部数据结构:短弱引用表和长弱引用表。

 

       两种类型的弱引用:

 

l         短弱引用不追踪复苏。

也就是说,一个有短弱引用的对象会被立即收回,而不用等到运行Finalize方法。

l         长弱引用追踪复苏。

也就是说,只有当长弱引用表中的对象的存储空间可收回的时候GC才回收这个对象。如果对象有Finalize方法,是在Finalize方法被调用了之后并且对象不能复活了。

 

       这两个表简单的存放着分配在托管堆中对象的指针。最初,两个表均为空。当你创建一个弱引用(WeakReference)对象时,对象不从托管堆中分配。而是在一个弱引用表中分配一个空的存储位置;短弱引用使用短弱引用表,长弱引用使用长弱引用表。

 

       让我们看一个例子,看看GC运行时会发生些什么。下面的图(图1和图2)显示了GC运行前和运行后所有内部数据结构的状态。

 

1GC运行前

 

2GC运行后

 

以下是GC运行时进行的操作:

 

1.  GC为所有可遍历的对象建一张图。在上面的例子中,图包含对象B,C,E,G

2.  GC扫描短弱引用表。如果表中指针指向的对象不在图中,那么这个指针标识的是一个不可遍历的对象,短弱引用表中的这个位置置为null。在上面的例子中,对象D的位置置为null,因为它不是图的一部分。

3.  GC扫描Finalization队列。如果队列中的指针所指的对象不在图中,那么这个指针标识一个不可遍历的对象,指针从Finalization队列中移到FReachable队列中。这时,对象被认为是可遍历的,所以加到图中。在上面的例子中,对象A,D,F是不包含在图中但看作是可遍历的对象,因为它们属于Finalization队列。进而Finalization队列被清空。

4.  GC扫描长弱引用表。如果表中的指针指的对象不在图中(现在图包括FReachable队列中指针所指的对象),那么指针标识一个不可遍历的对象,所在位置置为null。由于对象CF都包含在图中,都不置null

5.  GC整理(Compact)内存,挤出不可遍历对象留下的空隙。在上面的例子中,对象H是唯一从堆中删除的对象,它所分配的内存被收回。

 

代(Generations

       由于垃圾回收要在停止整个程序的情况下才能完成,它们可能会在程序执行期间进行任意长时间的中断。GC也有可能中断为满足实时系统的需求而要求及时响应的事件。

 

       GC中有一个特征叫代(Generations),就是专门为提高性能而设计的。一个多代的GC是通过对观察用各种语言编写的大部分程序而得到两个事实进行仔细分析而得到的:

 

1.  新创建的对象拥有更短的生命周期。

2.  越老的对象,存活的越久。

 

多代的回收器通过对象的年龄把它分成若干组,并且年轻的对象比年老的对象回收的更频繁。初始化时,托管堆不含任何对象。所有新的对象都被添加到第0代堆中,直到堆装满了并触发垃圾回收。由于大部分对象存活的时间很短,只有一小部分年轻的对象在第一次回收时存活下来。一旦一个对象在第一次回收后存活下来后,它就被提升到第1代。在垃圾回收后可以说新的对象都在第0代堆中。只有当第0代的堆装满时垃圾回收才会再次被触发。所有第0代存活下来的对象被整理提升到第1代中。然后第0代不含任何对象了,但是所有新的对象都进入了第0代。

 

因此,作为当前代中“成熟”(存活于多代回收器)的对象,它们都会被移到下一级更老的代中。第2代是CLRGC所支持的最大的代。以后回收时,第2代存活的对象将只是简单的停留在第2代。

 

因此,把堆划分成对象的代并且回收和整理更年轻的代中的对象提高了垃圾回收算法的效率,因为从堆中收回了大量的有意义的空间,同时比起回收器检查所有代中的所有对象要快得多。

 

一个能执行多代回收的GC,每次回收都要确保(至少要尽可能)所需时间小于某个最大时间,以帮助为实时环境能做一些配套的实时操作,同时也防止出现让用户明显感觉到的中断现象。

 

垃圾回收相关神话

GC显然比手工内存管理要慢

应解释:不是一定的。现代垃圾回收器看起来运行时和手工存储分配(malloc/freenew/delete)一样快。在一些特殊的程序中,垃圾回收运行的可能不如为用户专门设计的自定义内存分配那么快。但从另一方面说,为了使手工内存管理正确的工作而添加的额外代吗(比如说,显示的引用计数)常常比GC所做的要昂贵的多。

 

GC会使程序中断

对应解释:由于垃圾回收器在查找和回收垃圾对象时通常停止整个应用程序,他们可能会导致中断时间过长而让用户觉察到。但是通过现在优化计数,这些可以感觉到的中断完全可以避免。

 

手工内存管理不会导致中断

对应解释:手工内存管理并不能确保性能。它可能由于大量的分配或释放内存工作而导致中断。

 

使用GC的程序很大并且臃肿;GC不适合小的程序或系统

对应解释:尽管在复杂的系统中使用GC很有优势,也没有理由认为GC在其它尺寸的程序中会引入什么大的开销。

 

我已经听说了GC会使用两次大量的内存

对应解释:对于原来的GC这可能是个事实,但并不是垃圾回收器都是这样的。用于GC的数据结构比那些手工内存管理的要大的多。

 

 

.NET_C#_栈_堆_垃圾回收GC 图文并茂的讲解了.NET(C#) 框架下的内存管理机制(堆栈、堆及垃圾回收GC)。 文档为英文文献的中文译本,全文通俗易懂。 立即下载

相关推荐

c#垃圾回收资源.net回收机制

垃圾回收 《漫谈.Net中的自动垃圾收集机制》

.NET CLR之垃圾回收(GC)

Net程序可以找出某个时间点上哪些已分配的内存空间没有被程序使用,并自动释放它们。自动找出并释放不再使用的内存空间的机制,就称为垃圾回收机制(Garbage Collection,简称GC)。.NET CLR使用分代收集算法+标记压缩算法来进行GC。...

qq_35787977的博客 1471

.net回收机制

在进行.NET开发时,我们使用了许多对象。一些对象是非常大的,使用完毕后需要被销毁。对于这些对象,我们需要手动释放它们所占用的内存。但是,在有些情况下,我们可能会忘记释放内存,这会导致内存泄漏,影响程序的性能。此时垃圾回收机制就派上用场了。它可以自动地释放不再被程序使用的对象所占用的内存,从而避免内存泄漏。在这篇文章中,我们详细讲解了.NET回收机制的运作原理。我们了解到,回收机制可以自动释放内存,避免内存泄漏,减少手动内存管理的工作量,增强程序的安全性。

Documentlv的博客 991

.Net 垃圾回收详解

定义:.NET Framework提供了一个垃圾收集器(Garbage Collector),它是一个后台线程,周期性地运行,负责扫描和标记不再被引用的对象,并释放它们占用的内存。目标:通过自动回收内存来避免内存泄漏,减少手动内存管理的工作量,增强程序的安全性。

Code365 1222

.NET中的垃圾回收原理全解

.NET中的垃圾回收(Garbage Collection)是一种自动内存管理机制,它负责在程序运行时自动回收不再使用的内存对象,以减轻开发人员的内存管理负担。以下是.NET垃圾回收的原理解析:垃圾收集器(Garbage Collector,简称GC):.NET Framework提供了一个垃圾收集器,它负责扫描和标记不再被引用的对象,并释放它们占用的内存。垃圾收集器是一个后台线程,周期性地运行。...

dotNET跨平台 604

了解 .Net 中的垃圾回收

概述:了解垃圾回收.NET 中的垃圾回收是一项自动内存管理功能,用于处理应用程序的内存分配和释放。.NET GC 在托管堆上运行,托管堆是用于存储 C# 应用程序中实例化的对象的内存区域。GC 的工作????原理概括地说,.NET GC 的工作方式分为三个步骤:标记:GC 从根开始遍历所有对象引用,以识别哪些对象仍在使用中。重新定位:然后,它通过将仍在使用的对象移得更近来压缩堆,并相应地更新引用。清除:...

dotNET跨平台 386

了解.NET中的垃圾回收

原文来自互联网,由长沙DotNET技术社区编译。尽管这是一篇来自2009年的古老的文章,但或许能够对你理解GC产生一些作用。了解.NET中的垃圾回收一旦了解了.NET垃圾收集器是如何...

dotNET跨平台 512

.net 垃圾回收

    .Net所指的托管只是针对内存这一个方面,并不是对于所有的资源;因此对于Stream,数据库的连接,GDI+的相关对象,还有Com对象等等,这些资源并不是受到.Net管理而统称为非托管资源。而对于内存的释放和回收,系统提供了GC-Garbage Collector,而至于其他资源则需要手动进行释放。 那么第二个概念就是什么是垃圾,通过我以前的文章,会了解到.Net类型分为两大类,一个就

fsyiyun的专栏 564

.NET中的垃圾回收

                                                      .NET中的垃圾回收                                                cloud(翻译) 来源:CSDN 目录l         导言l         关于垃圾回收l         垃圾回收算法m        应用程序根(App

≡≡奋斗中的猫≡≡ 1803

.NET垃圾回收机制

  在.NET Framework中,内存中的资源(即所有二进制信息的集合)分为"托管资源"和"非托管资源".托管资源必须接受.NET Framework的CLR(通用语言运行时)的管理(诸如内存类型安全性检查),而非托管资源则不必接受.NET Framework的CLR管理. (了解更多区别请参阅.NET Framework或C#的高级编程资料)   托管资源在.NET Framework中又分

梦想MVP 8723

浅谈.NET垃圾回收

最近在做Winform项目优化,项目运行十天,内存就达到3G,真是让人头疼,到现在还没有完全解决,,,下面来说说.NET垃圾回收原理与算法 每个程序都有这样或者那样的资源,如数据库连接、网络连接、文件操作等等。在面向对象的环境里,每一个类型、每一个程序所用的资源都对应着自己的内存空间,要想使用它们必须为相应的类型实例分配一定的内存空间。 .NET创建一个对象使用new关键字,在

xiaoyiyz的专栏 1665

.NET 垃圾回收浅解

在说明垃圾回收的实现机制之前,先说明一下垃圾回收存在的背景。 垃圾回收器(GC)是.NET平台中一个很重要的组成部分,.NET垃圾回收机制降低了编写程序的复杂程度,使程序员不用耗费精力去处理析构,成功的将内存管理从程序的编写时,脱离到运行时。 一、析构函数 析构函数的作用主要是释放类在构造函数中以及类生命周期中所获取的资源,比如需要释放互斥锁、...

106

.NET中的垃圾回收(上)

目录l         导言l         关于垃圾回收l         垃圾回收算法m        应用程序根(Application Roots)l         实现m        阶段I: 标记(Mark)m        阶段II: 整理(Compact)l         终结(Finalization)l         垃圾回收性能的

Jerry的专栏 2583

.NET 垃圾回收GC概述

垃圾回收(GC)是 .NET 自动管理内存的机制,核心是 “标记 - 清理 - 压缩”。通过 “分代回收优化性能,优先回收短期对象,减少对程序的影响。开发者无需手动释放内存,但需注意合理使用对象,避免不必要的 GC 压力。简单说,GC 就像一个 “自动清洁工”,定期清理程序中不再需要的内存 “垃圾”,让程序更稳定、更安全。

wlq_567的博客 972

如何理解.net中的垃圾回收机制

.NET Framework 的垃圾回收器管理应用程序的内存分配和释放。每次您使用 new 运算符创建对象时,运行库都从托管堆为该对象分配内存。只要托管堆中有地址空间可用,运行库就会继续为新对象分配空间。但是,内存不是无限大的。最终,垃 圾回收器必须执行回收以释放一些内存。垃圾回收优化引擎根据正在进行的分配情况确定执行回收的最佳时间。当垃圾回收器执行回收时,它检查托管堆中不再被 应用程序...

weixin_33878457的博客 1714

.NET里的垃圾回收编程

.NET 框架的垃圾回收器管理应用程序的内存分配和释放。每次您使用 new 运算符创建对象时,运行库都从托管堆为该对象分配内存。只要托管堆中有地址空间可用,运行库就会继续为新对象分配空间。但是,内存不是无限大的。最终,垃圾回收器必须执行回收以释放一些内存。垃圾回收优化引擎根据正在进行的分配情况确定执行回收的最佳时间。当垃圾回收器执行回收时,它检查托管堆中不再被应用程序使用的对象并执行必要的操作来

Paul_Ni的专栏 2084
下一篇: .NET中的垃圾回收(上)
cloud
博客等级 码龄27年 58粉丝 1276原创
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值