.NET中的垃圾回收(上)

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

目录

l         导言

l         关于垃圾回收

l         垃圾回收算法

m        应用程序根(Application Roots)

l         实现

m        阶段I: 标记(Mark)

m        阶段II: 整理(Compact)

l         终结(Finalization)

l         垃圾回收性能的优化

m        弱引用(WeakReference)

m        代(Generations)

l         垃圾回收相关的神话

 

导言

       微软声称.NET是一种革命性的编程技术。许多要素使它成为大多数开发人员的首选。本文我们将要讨论一下.NET Framework中一个很主要的优势——内存和资源管理的便捷性。

 

关于垃圾回收器

       每个程序都会使用一定次序的资源,或内存缓冲区,或网络连接,或数据库资源等等。实际上,在面向对象环境中,每种类型都被看作是程序的某些有效资源。为了使用这些资源,必须分配部分内存来描述这种类型。

 

       资源访问按一下步骤进行:

 

1.    为类型分配内存来描述资源。

2.    初始化资源,把资源设置成初始化状态,使资源可用。

3.    通过访问类型实例的成员来使用资源(按需求重复)。

4.    销毁资源状态以清除资源。

5.    释放内存。

 

.NET中的垃圾回收器(GC)完全彻底帮助开发人员从追踪内存的使用和确定什么时候释放内中解脱出来。

 

Microsoft® .NET CLR (公共语言运行库)要求所有资源都从托管堆中进行分配。你无需释放托管堆中的对象——当应用程序不再需要这些对象时,对象将被自动释放。

 

内存不是无限的。垃圾回收器需要执行回收以便释放内存。垃圾回收器的优化引擎会对已做的分配选择最好的回收时间(准确标准由微软提供)。当垃圾回收器执行回收时,它先找出托管堆中不再被应用程序使用的对象然后执行相应操作收回这些对象的内存空间。

 

       然而,为了进行自动内存管理,GC必须知道根的位子。也就是说,它应该知道一个对象什么时候不再被应用程序使用了。在.NET中,GC是通过一个称之为元数据的东西了解到这些的。.NET中使用的每种数据类型都通过元数据来描述它。在元数据的帮助下,CLR知道内存中每个对象的布局,在垃圾回收的整理阶段给GC提供帮助。没有这些信息,GC将不会知道一个对象在哪儿结束和下一个从哪儿开始。

 

垃圾回收算法

应用程序根(Application Roots)

       每个应用程序都有一套根(Roots)。根标识存储位置,这个位置或者指向一个托管堆的对象,或者指向一个空对象(null)。

 

比如:

 

l         一个应用程序中所有全局和静态对象指针。

l         一个线程堆栈中所有局部变量/参数对象指针。

l         托管堆中所有CPU登记的对象指针。

l         FReachable队列中的对象指针。

 

活动根的表由JIT编译器和CLR维护,并且对于垃圾回收器的算法是访问。

 

实现

.NET中的垃圾回收是用跟踪回收实现的,确切的说CLR实现了标记(Mark)/整理(Copact)回收器。

 

这个方法有以下两个阶段组成:

 

阶段I:标记(Mark)

找到可以被收回的内存。

 

当GC开始运行时,它假设堆中的所有对象都是垃圾。换句话说,它假设应用程序的根没有指向堆中的的任何对象。

 

阶段I中包含下列步骤:

 

1.  GC识别存活对象的引用或应用程序根。

2.  从根开始遍历,建一张可以从根遍历的所有对象的图。

3.  如果GC准备尝试添加一个已经在图中的对象,它就停止这条路径的遍历。这样做有两个目的,第一个是极大的优化性能,因为它不会遍历一套对象一次以上。第二是防止当有对象的循环连接列表时而发生死循环,因此循环被有效的控制了。

 

一旦所有的根都被检查完后,垃圾回收器的图中包含了所有可以从应用程序根遍历到的对象。任何不再图中的对象都不能被应用程序访问到,也就是所谓的垃圾。

 

阶段II:整理(Compact)

把所有存活的对象移到堆的末端,空出堆顶端的空间。

 

阶段II包含下列步骤:

 

1.  现在GC线性地遍历堆,寻找邻近的垃圾对象块(现在被认为是空闲空间)。

2.  然后GC往下移动内存中的非垃圾对象,去掉堆中的所有空隙。

3.  移动内存中的对象导致对象指针失效。因此GC需要修改应用程序的根使对象的指针指向新的位置。

4.  另外,如果对象包含一个指向其它对象的指针,GC也会负责纠正这些指针。

 

在所有垃圾被标识完以后,所有的非垃圾对象也被整理,并且所有非垃圾对象的指针也被修正,最后一个非垃圾对象后的指针指向下一个被添加对象的位置。

 

终结(Finalization)

 

.NET Framework的垃圾回收器能暗中追踪由应用程序创建的对象的生命周期,但是当它遇到对象包装了非托管资源(比如文件、窗口或网络连接等)时却无能为力。

 

一旦应用程序不再使用那些非托管资源时需要显示地释放它们。.NET Framework为对象提供了终结(Finalize)方法:在垃圾回收器收回这个对象的内存时,必须执行对象的这个方法来清除它的非托管资源。由于缺省的Finalize方法什么都没做,如果需要显示清除资源必须覆盖这个方法。

 

如果一把Finalize方法当作只是C++中析构函数另外一个名字那也不足为怪。虽然它们都被赋予了释放对象占有的资源的任务,但是它们还是有很不相同的语义。在C++中,当对象推出作用域时析构函数会立刻被调用,而Finalize方法是在起动垃圾回收清除对象时才被调用的。

 

.NET中,由于终结器(Finalizer)的存在使得垃圾回收的工作变得更加复杂了,因为它在释放对象前增加了许多额外的操作。

 

无论什么时候,在堆上分配一个含有Finalize方法的新对象时,都会有一个指向这个对象的指针被添加到一个称为Finalization队列的内部数据结构当中。当对象不能再次被遍历到时,GC就认为这个对象是垃圾。GC首先扫描Finalization队列查找这些对象的指针,当指针被找到时,把它从Finalization队列中去掉并添加到另外一个名为FReachable队列的内部数据结构中,使这个对象不再是垃圾的一部分。这时,GC完成了确定垃圾。然后整理(Compact)可收回的内存,由专门的线程负责清空FReachable队列并执行对象的Finalize方法。

 

第二次垃圾回收器被触发的时候,它把被终结(Finalize)的对象看作真正的垃圾,然后简单的释放它们的内存。

 

由此可知当一个对象需要终结时,它先死,然后存活(复活),然后再次并且最终地死去。推荐避免使用Finalize方法,除非有需要。Finalize方法会增加内存压力,因为直到两次垃圾回收被启动时,对象占用的内存和资源才会得到释放。因此你无法控制两次Finalize方法执行的顺序,它可能会导致无法预料的后果。

 

 

 

MatLab Desired port was :31515解决方案 前言:使用的MatLabR2022b今天突然出现了错误,在程序中打不开文件。后尝试了下面的方法,可以解决。后面还有另一种方法,上面方法如果行不通,大家可以尝试一下。搜索栏输入:firewall.cpl。找到相关项,右键属性,设置为允许。 阅读详情

相关推荐

antv x6 沿边图标循环动画实现

2.使用transition给边设置动画,利用complte方法实现循环动画。实现效果,如下图,边上存在两个图标,要求图标延边一直循环动画。1.注册一个自定义边,边上定义两个图标,并设置其初始位置。

lingliu0824的博客 3366

.net的回收机制

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

Documentlv的博客 997

【Cadence软件技巧集萃】从Capture到Allergo——分布演示从原理符号导出到网络表

Cadence软件功能多样、性能强大,但是使用起来颇费步骤,尤其是从原理图到网络表的导入步骤,没有经过上手实践还真不一定一次就能搞定哩。本文笔者用将分步演示:1、在Capture软件上绘制原理图;2、将原理图导出网络表;3、在Allergo软件上更新网络表;希望给予使用Cadence的读者有效的帮助1、本文简述了建立Capture项目的步骤,演示了调用元件符号库的方法,并绘制了电气原理图;2、针对加载元件封装库可能遇到的问题,做了排查步骤建议;

qq_33175704的博客 2530

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

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

dotNET跨平台 610

BGE-Reranker-v2-M3介绍

重排序模型介绍

吉米_王 5887

转录组PCA分析3大常见误区:数据标准化、离群样本与批次效应处理

本文深入探讨转录组PCA分析中的三大常见误区:数据标准化、离群样本识别与批次效应处理。通过实战案例和R代码演示,揭示如何优化PCA结果以提升生物学解释力,特别关注数据标准化策略的选择和批次校正方法的应用,帮助研究者避免常见陷阱并获得可靠的转录组分析结果。

weixin_28362173的博客 370

.Net 垃圾回收详解

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

Code365 1240

华为OD机试 - 城市聚集度(Python/JS/C/C++ 2025 A卷 200分)

华为OD机试 2025A卷题库疯狂收录中,刷题。

学Java,找哪吒 1129

了解 .Net 中的垃圾回收

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

dotNET跨平台 387

自建 HTML获取腾讯六宫格点选图片验证码素材,实现刷新批量获取图片方便训练

通过自建 HTML 页面,可以方便地获取腾讯六宫格二维码素材,不仅过程简单,而且可以灵活配置各种参数。希望这篇文章能帮助到需要相关素材的小伙伴。如果你有其他问题或者更好的方法,欢迎留言交流!

代码简单说 Vue、JAVA、PHP、Node.js 熟练运用,接口、架构、性能全搞定。 479

DeepSeek 赋能太空探索:从轨道优化到星际开拓的 AI 革命

随着人工智能技术蓬勃发展,DeepSeek 在太空探索领域展现出巨大应用潜力。本文深入剖析 DeepSeek 技术核心,包括低功耗运算、开源生态等优势,阐述其与传统航天技术的差异。从航天器自主控制、深空探测、载人航天等关键环节,结合实时轨道调整、故障诊断修复等实例,揭示 DeepSeek 对航天任务效率与安全性的提升作用。同时探讨其应用面临的太空环境适应、伦理安全等挑战,展望技术演进方向及与前沿技术融合前景,展现 DeepSeek 为人类太空探索带来的变革与深远意义。

邓邓子的博客 2255

.Net的垃圾回收机制

.Net 的垃圾回收机制什么是垃圾回收机制Garbage Collector如何处理对象处理值类型对象处理引用类型对象引用类型对象的处理机制引用类型对象的存放机制小对象堆的处理机制 什么是垃圾回收机制 在.Net 平台,用户可以手动也可以通过.Net提供的垃圾收集器Garbage Collector(后称GC)释放被占用的资源。总所周知,.Net的内存分为可管理内存和不可管理内存,可管理内存包括栈stack和可管理堆managed heap,不可管理内存就是不可管理堆,包括文件的Handler、数据库的Co

CSharpIsDog的博客 5075

实现端到端加密的WebRTC视频会议终端

需要注意的是,上述示例代码中没有涉及到具体的加密算法和密钥交换过程,而是通过WebRTC API自动处理了加密和密钥交换的细节。然后,我们通过信令服务器将本地SDP发送给对方,并接收对方的SDP。最后,我们将对方的SDP设置为远程描述,并将最终的连接建立起来。最后,我们将对方的SDP设置为远程描述,并建立最终的连接。在本文中,我们将探讨如何使用WebRTC构建一个加密的视频会议终端,并提供相应的源代码。在本文中,我们将探讨如何使用WebRTC构建一个加密的视频会议终端,并提供相应的源代码。

WaJulia的博客 430

了解.NET中的垃圾回收

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

dotNET跨平台 513

复分析 阿尔福斯(Ahlfors) 第三版答案 英文

答案分为十章,有部分习题没有答案,全英文复分析阿尔福斯(Ahlfors) 第三版答案

win10 跳过U8环境检测的IE WebControls.rar

win10 安装u8的时候 提示IE WebControls 不通过,这个工具可以欺骗u8的检查。 跳过U8环境检测的IE WebControls。提示导入失败后,重新检测通过。

.net 垃圾回收

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

fsyiyun的专栏 566

RU DOS版、EFI版32bit/64bit BIOS常用工具

DOS版、EFI版的RU工具,可用来查看IO、MEM、PCI、SMBIOS等资源。亲测在EFI SHELL下可用。

.NET中的垃圾回收

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

≡≡奋斗中的猫≡≡ 1808

Statistics and Machine Learning Toolbox

Statistics and Machine Learning Toolbox(带书签),MATLAB统计学习工具

.NET垃圾回收机制

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

梦想MVP 8729

浅谈.NET垃圾回收

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

xiaoyiyz的专栏 1667

.NET 垃圾回收浅解

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

110

.NET CLR之垃圾回收(GC)

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

qq_35787977的博客 1476

.NET 垃圾回收GC概述

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

wlq_567的博客 975

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

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

weixin_33878457的博客 1715

.NET垃圾回收

.NET垃圾回收   2009-02-09 11:50:06|  分类: 编程技术 |  标签: |举报 |字号大中小 订阅               下载LOFTER 我的照片书  | 首先,对象分为值类型和引用类型,值类型在用完后是由操作系统自动回收的,引用类型由垃圾回收器回收,所以提到

autumn20080101的专栏 1963

.NET高级面试指南专题八【 垃圾回收机制GC】

总体而言,.NET的垃圾回收机制是CLR(Common Language Runtime)的一部分,它通过自动追踪和释放不再使用的对象,确保.NET应用程序的内存使用是高效和可靠的。需要注意的是,垃圾回收的触发时机是由垃圾回收器实现决定的,具体情况可能会因编程语言、运行时环境和垃圾回收算法的不同而异。垃圾回收的触发条件一般与各代的内存使用情况相关。例如,新生代的触发条件可能是新生代的内存空间即将用完,中生代的触发条件可能是新生代的回收次数达到一定阈值,老生代的触发条件可能是老生代的内存空间即将用完。

一个专注于技术研究创新的程序员 2014
上一篇: .NET中的垃圾回收(下)
下一篇: Control的Region属性
cloud
博客等级 码龄27年 60粉丝 1276原创
评论 1
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值