C#探索之路(4):浅析C#中的托管、非托管堆栈与垃圾回收

这篇具有很好参考价值的文章主要介绍了C#探索之路(4):浅析C#中的托管、非托管堆栈与垃圾回收。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

C#探索之路(4):浅析C#中的托管、非托管堆栈与垃圾回收

一、C#托管服务下的几个重要概念:

1、 托管代码:

1、使用 .NET 时,我们经常会遇到“托管代码”这个术语。

2、简而言之,托管代码就是执行过程交由运行时管理的代码。

2、CLR阶段:

1、在托管服务下,相关的运行时称为公共语言运行时 (CLR)。

2、不管使用的是哪种实现(例如 Mono、.NET Framework 或 .NET Core/.NET 5+)。 CLR 负责提取托管代码、将其编译成机器代码,然后执行它。

3、 除此之外,运行时还提供多个重要服务,例如自动内存管理(也也就是后面提到GC机制)、安全边界、类型安全,等等。

3、非托管代码:

1、概念:

在公共语言运行库环境的外部,由操作系统直接执行的代码

2、区别:

非托管代码必须提供自己的垃圾回收、类型检查、安全支持等服务,它与托管代码不同,后者从公共语言运行库中获得这些服务,而非托管代码是在运行库之外运行的代码。例如COM 组件、ActiveX 接口和 Win32 API 函数都是非托管代码的示例。

3、C#官方文档做出的说明:

在非托管环境中,程序员需要亲自负责处理相当多的事情。 实际的程序在本质上是操作系统 (OS) 载入内存,然后启动的二进制代码。 其他任何工作 - 从内存管理到安全考虑因素 - 对于程序员来说是一个不小的负担。

托管代码是使用可在 .NET 上运行的一种高级语言(例如 C#、Visual Basic、F# 等)编写的。 使用相应的编译器编译以这些语言编写的代码时,无法获得机器代码, 而是获得中间语言代码,然后运行时会对其进行编译并将其执行。 C++ 是这条规则的一个例外,因为它也能够生成可在 Windows 上运行的本机非托管二进制代码。

4、中间语言(IL、CIL、MSIL):

1、简称:

什么是“中间语言”(简称 IL)?中间语言有时也称为公共中间语言 (CIL) 或 Microsoft 中间语言 (MSIL)。

2、概念:

中间语言其实意如其名,意思就是一个从高级语言转成机器码中间的过度语言,因为大体的流程其实是这么一回事

①开发者使用的高级语言编写功能实现代码

---->②LC(Language Complier我们通常称之为解释器,也就是编译器内置的解释器)

---->③MSIL(IL\CIL)---->通过CLR和JIT实时编译运行将IL代码转成对应的机器码(即二进制码)

---->④机器通过执行机器码实现对应的功能效果;

(看到了这,我恍然大悟,大学科目原来是这么用的啊,可算是圆回来了hhhhhhh,“*(不能明说的字)” 原来硬件是这么用的啊,寄存器,CPU其实说白了就是一个机器码执行器,这么说其实有问题,对于cpu大家可以参考这个链接:cpu的相关概念)

C#探索之路(4):浅析C#中的托管、非托管堆栈与垃圾回收

5、托管代码互操作性

当然,CLR 允许越过托管与非托管环境之间的边界,同时,即使在基类库中,也有很多代码可以做到这一点。 这称为互操作性,简称 interop。 例如,使用这些机制可以包装某个非托管库以及调用该库。 但是,请务必注意,如果采取这种方法,当代码越过运行时的边界时,实际的执行管理将再次交接到托管代码,因而需要遵守相同的限制。

与此类似,C# 语言可让你利用所谓的不安全上下文(指定执行过程不由 CLR 管理的代码片段),在代码中直接使用非托管构造,例如指针。

至于托管代码的互操作性,我目前还不是很明确但是查究到了这么一篇文章【转帖】 CLR 全面透彻解析:托管和本机代码互操作性,讲述的挺好的,那我不经发出了疑问,那是不是有的Unity的C#的热更方案就有用到这个托管代码的互操作性呢?提出一个问题(这个问题以后有待考究),有了解或者使用过这个大佬的博友看到过,希望给出对应的解释和回答,或者在评论区贴上对应的链接,不甚感激!!!!
C#探索之路(4):浅析C#中的托管、非托管堆栈与垃圾回收

二、垃圾回收机制:

杂谈:

以前谈到C#中的GC(Garbage Collector-垃圾收集器),仅就内存而言的垃圾收集。我们在自己心中都有一个概念就是C#中有这么一种内存管理方案来帮助开发者自动取管理内存,释放掉我们没有使用的内存资源,从而把内存资源分配给我们正在使用的对象上去;

但是当我回过头来了解这个垃圾回收机制的时候,我发现了一个很有意思的事情,当我去查询相关的资料的时候我发现,这其中的原理真的是一环扣一环,还环环不一样,我的内心:(TM*燃起来了!)。相反导致这个有意思的方法勾起了我的探索欲,这到底是个什么玩意儿,究竟神奇在哪;

1、垃圾回收的基本概念:

.NET 的垃圾回收器管理应用程序的内存分配和释放。 每当有对象新建时,公共语言运行时都会从托管堆为对象分配内存。 只要托管堆中有地址空间,运行时就会继续为新对象分配空间。 不过,内存并不是无限的。 垃圾回收器最终必须执行垃圾回收来释放一些内存。 垃圾回收器的优化引擎会根据所执行的分配来确定执行回收的最佳时机。 执行回收时,垃圾回收器会在托管堆中检查应用程序不再使用的对象,然后执行必要的操作来回收其内存。

概括:就是GC会帮你自动管理内存,分配内存,回收内存,采用的就是对应的GC的算法。

2、垃圾回收带来的优点:

垃圾回收器具有以下优点:

  • 开发人员不必手动释放内存。
  • 有效分配托管堆上的对象。
  • 回收不再使用的对象,清除它们的内存,并保留内存以用于将来分配。 托管对象会自动获取干净的内容来开始,因此,它们的构造函数不必对每个数据字段进行初始化。
  • 通过确保对象不能自己使用分配给另一个对象的内存来提供内存安全。
  • 在公共语言运行时 (CLR) 中,垃圾回收器 (GC) 用作自动内存管理器。 垃圾回收器管理应用程序的内存分配和释放。 对于使用托管代码的开发人员而言,这就意味着不必编写执行内存管理任务的代码。 自动内存管理可解决常见问题,例如,忘记释放对象并导致内存泄漏,或尝试访问已释放对象的内存。

3、垃圾回收机制具体做了什么:

垃圾回收主要有这么几个阶段:

  • 标记阶段,找到并创建所有活动对象的列表。
  • 重定位阶段,用于更新对将要压缩的对象的引用。
  • 压缩阶段,用于回收由死对象占用的空间,并压缩幸存的对象。 压缩阶段将垃圾回收中幸存下来的对象移至段中时间较早的一端。
  • 因为第 2 代回收可以占用多个段,所以可以将已提升到第 2 代中的对象移动到时间较早的段中。 可以将第 1 代幸存者和第 2 代幸存者都移动到不同的段,因为它们已被提升到第 2 代。

垃圾回收器使用以下信息来确定对象是否为活动对象:

  • 由实时 (JIT) 编译器和堆栈查看器提供的堆栈变量。 JIT 优化可以延长或缩短报告给垃圾回收器的堆栈变量内的代码的区域。
  • 指向托管对象且可由用户代码或公共语言运行时分配的句柄。
  • 应用程序域中可能引用其他对象的静态对象。 每个应用程序域都会跟踪其静态对象。

然而这里面所指代的第几代第几代实际上就是C#官方文档所讲述到的幸存与提升,感兴趣的朋友可以到官方文档里面了解其中的细节,因为牵扯的内容太多太杂,我觉得太杂反而不利于去理解其中的核心过程,就不做赘述了,请网友自行查阅吧。

在查询资料的时候看到了其他博主形象的把官方文档的内容通过示意图画出来了,还挺有意思的:

大概传达的一个意思就是:

GC:“你们不用这块内存了是吧?那我把你们排挤出去了奥,你们谁还要续租使用的,可以继续保留,但是前提是此时已经不是原来的内存了,已经是一块新分配的内存了”;

为了方便了解其中的内容,可以试着用租房与房东之间的关系来具体理解;

该图片转载自:
C#关于托管资源GC垃圾回收与非托管资源继承 IDisposable接口 实现 Dispose方法释放非托管资源
C#探索之路(4):浅析C#中的托管、非托管堆栈与垃圾回收
该图片转载自:

C#垃圾回收机制GC

C#探索之路(4):浅析C#中的托管、非托管堆栈与垃圾回收

4、垃圾回收机制的注意事项:

  • 对于应用程序创建的大多数对象,可以依赖垃圾回收器自动执行必要的内存管理任务。 但是,非托管资源需要显式清除。

  • 最常用的非托管资源类型是包装操作系统资源的对象,例如,文件句柄、窗口句柄或网络连接。

  • 创建封装非托管资源的对象时,建议在公共 Dispose 方法中提供必要的代码以清理非托管资源。 通过提供 Dispose 方法,对象的用户可以在使用完对象后显式调用释放其内存。

  • 使用using和try/finally清理资源,

  • 所有非托管资源的类型必须显式地使用IDisposable接口的Dispose()来释放。所有封装或使用了非托管资源的类型都实现了IDisposable,这些类型在终结器中也会调用Dispose(),以便在忘记的时候仍能保证正常释放资源。不过这些资源将在内存中停留更长时间,应用程序也会变成资源消耗大户。(此条目收录自C# 学习笔记 .Net资源管理)

    若想使用一个可销毁的对象,那么using语句能够以最简单的方式保证你的对象可以正常销毁。using语句将生成一个try/finally块,包裹住分配的对象。这两段代码生成的IL完全一致:

    C#探索之路(4):浅析C#中的托管、非托管堆栈与垃圾回收

参考链接:

cpu的相关概念

C#关于托管资源GC垃圾回收与非托管资源继承 IDisposable接口 实现 Dispose方法释放非托管资源

C# 学习笔记 .Net资源管理

C#垃圾回收机制GC

C#官方文档之垃圾回收的托管服务相关概念说明

C#官方文档之垃圾回收的相关概念文档说明

【转帖】 CLR 全面透彻解析:托管和本机代码互操作性
c#中的托管、非托管、垃圾回收、using


以上呢,便是我对托管、非托管堆栈与C#垃圾回收作出的简要的描述,希望能够对你有所帮助~ 也希望你能够点赞、评论吖~ 你们的点赞、评论就是我前进的动力!


C#探索之路(4):浅析C#中的托管、非托管堆栈与垃圾回收
公众号:平平无奇代码猴
也可以搜索:Jackiie_wang 公众号,欢迎大家关注!欢迎催更!留言!

作者:ProMer_Wang

链接:https://blog.csdn.net/qq_43801020/article/details/127601735

本文为ProMer_Wang的原创文章,著作权归作者所有,转载请注明原文出处,欢迎转载!文章来源地址https://www.toymoban.com/news/detail-453005.html

到了这里,关于C#探索之路(4):浅析C#中的托管、非托管堆栈与垃圾回收的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • JVM 中的垃圾回收策略

    C 语言中,malloc 的内存必须 手动 free,否则容易出现内存泄漏(光申请内存,不释放,内存用完了,导致程序崩溃)。 JVM 的垃圾回收,GC,可以帮助程序员自动释放内存。 GC 能够有效的减少内存泄漏出现的概率! Java 运行时的各个内存区域,对于程序计数器、虚拟机栈、本

    2024年02月16日
    浏览(31)
  • java中的垃圾回收算法

    java中有四种垃圾回收算法,分别是: 标记清除法、标记整理法、复制算法、分代收集算法 1、标记清除法: 第一步:利用可达性去遍历内存,把存活对象和垃圾对象进行标记; 第二步:在遍历一遍,将所有标记的对象回收掉; 特点:效率不行,标记和清除的效率都不高;标记和清除

    2024年02月15日
    浏览(24)
  • JVM中的垃圾回收机制

    java相较于c、c++语言的优势之一是自带垃圾回收器,垃圾回收是指 不定时 去堆内存中清理 不可达 对象。不可达的对象并不会 马上 就会直接回收, 垃圾收集器在一个Java程序中的执行是自动的,不能强制执行,程序员唯一能做的就是通过调用System.gc 方法来建议执行垃圾收集

    2024年02月16日
    浏览(35)
  • JavaScript中的垃圾回收机制

    前端入门之旅:探索Web开发的奇妙世界 记得点击上方或者右侧链接订阅本专栏哦 几何带你启航前端之旅 欢迎来到前端入门之旅!这个专栏是为那些对Web开发感兴趣、刚刚踏入前端领域的朋友们量身打造的。无论你是完全的新手还是有一些基础的开发者,这里都将为你提供一

    2024年02月07日
    浏览(36)
  • C#垃圾回收器GC、析构函数(Finalize 方法)和Dispose

    GC(Garbage Collection)是.NET中的垃圾回收器。以应用程序的root为基础,遍历应用程序在Heap上动态分配的所有对象,通过识别它们是否被引用,来确定哪些对象是已经死亡的,哪些仍需要被使用。已经不再被应用程序的root或者别的对象所引用的对象就是已经死亡的对象,即所谓的

    2024年02月14日
    浏览(21)
  • HDFS中的Trash垃圾桶回收机制

    回收站(垃圾桶)是windows操作系统里的一个系统文件夹,主要用来存放用户历史删除的文档文件资料,存放在回收站的文件可以恢复 回收站的功能给了我们一剂“后悔药”。回收站保存了删除的文件,文件夹,图片等。这些项目将一直保留在回收站中,直到清空回收站 HDF

    2024年02月13日
    浏览(28)
  • lua学习笔记21完结篇(lua中的垃圾回收)

    输出 学习地址  【唐老狮】Unity热更新之Lua语法_哔哩哔哩_bilibili 

    2024年04月15日
    浏览(35)
  • PHP快速实战20-PHP7中的垃圾回收机制与原理讲解

    本文已收录于PHP全栈系列专栏:PHP快速入门与实战 在计算机程序中,垃圾回收指的是一种自动管理内存的技术。在程序执行过程中,分配给它的内存会随着对象的创建和销毁不断发生变化,如果没有垃圾回收,这些不再被使用的内存会一直占用系统资源,最终导致系统崩溃。

    2024年02月08日
    浏览(36)
  • 【Java高级应用:深入探索Java编程的强大功能,JVM 类加载机制, JVM 内存模型,垃圾回收机制,JVM 字节码执行,异常处理机制】

    本人详解 作者:王文峰,参加过 CSDN 2020年度博客之星,《Java王大师王天师》 公众号:JAVA开发王大师,专注于天道酬勤的 Java 开发问题 中国国学、传统文化和代码爱好者的程序人生,期待你的关注和支持!本人外号:神秘小峯 山峯 转载说明:务必注明来源(注明:作者:

    2024年01月16日
    浏览(71)
  • C#探索之路基础夯实篇(5):语法糖概念解析

    从之前一开始接触lua的时候开始,开始第一次接触到语法糖,后续在看电子书籍的时候屡屡提及到语法糖这个概念,那么语法糖到底是什么呢? 语法糖的概念可以理解为某一段代码的简写或简化形式。它并不是新增功能或语言结构,而是一种更便捷的书写方式,可以使代码更

    2024年04月29日
    浏览(37)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包