C# 应用程序退出时会自动释放托管资源吗?

2023-11-24

我完全知道 using 语句是处理的方式IDisposables。请不要在评论中重复此建议。

当 C# .NET 4.5(或更高版本)应用程序关闭时,会发生什么IDisposable哪些没有得到妥善处置?

我知道有些有一个用于处理非托管资源的终结器。

但假设我有一个控制台应用程序,带有静态Stream多变的。当我关闭控制台应用程序时它会被释放吗?

怎么样一个HttpClient?你怎么知道在哪些情况下它会起作用,在哪些情况下不会呢?

好吧,现在一些实际的背景信息。我经常储存某些IDisposables 作为字段,迫使我的班级实施IDisposable。最终用户应该使用 using。但如果这没有发生怎么办?

GC 之前是否只是不必要的内存?或者你突然出现内存泄漏?


区分实现的对象很重要IDisposable以及带有终结器的对象。在大多数情况下(可能最好是所有情况),带有终结器的对象也实现IDisposable但实际上它们是两个不同的东西,而且最常一起使用。

终结器是一种向 .NET 运行时告知在收集对象之前必须执行终结器的机制。当 .NET 运行时检测到某个对象符合垃圾回收条件时,就会发生这种情况。通常情况下,如果对象没有终结器,则会在本次收集期间将其收集。如果它有终结器,它将被放置到一个列表中,即“易碎队列”,并且有一个后台线程监视该线程。有时,在集合将对象放入此队列后,终结器线程将处理此队列中的对象并调用终结器方法。

一旦发生这种情况,该对象再次符合收集条件,但它也被标记为finalized,这意味着当垃圾收集器在未来的收集周期中找到该对象时,它不再将其放入此队列中,而是正常收集它。

请注意,在上面的文字段落中,IDisposable一次都没有被提及,这是有充分理由的。以上均不依赖于IDisposable at all.

现在,对象实现IDisposable可能有也可能没有终结器。一般规则是,如果对象本身拥有非托管资源,它可能应该拥有,如果不拥有,它可能不应该拥有。(我在这里犹豫是否要说“总是”和“从不”,因为似乎总是有人能够找到一个角落案例,以某种方式有意义,但打破了“通常”规则)

A TL;DR上面的总结可能是,终结器是一种在收集对象时(半)保证清理对象的方法,但具体何时发生并不直接由程序员控制,而实现IDisposable是直接从代码控制此清理的一种方法。

不管怎样,有了这些,让我们来解决您的具体问题:

当 C# .NET 4.5(或更高版本)应用程序关闭时,未正确处置的 IDisposables 会发生什么情况?

Answer:没有什么。如果它们有终结器,则终结器线程将尝试拾取它们,因为当程序终止时,all对象有资格被收集。然而,不允许终结器线程“永远”运行来执行此操作,因此它也可能会耗尽时间。另一方面,如果对象实现IDisposable没有终结器,它只会被正常收集(同样,IDisposable与垃圾收集完全没有关系)。

但假设我有一个控制台应用程序,带有静态 Stream 变量。当我关闭控制台应用程序时它会被释放吗?

Answer:不,不会的disposed. Stream它本身是一个基类,因此根据具体的派生类,它可能有也可能没有终结器。然而,它遵循与上面相同的规则,因此如果它没有终结器,它将被简单地收集。例子,内存流没有终结器,而文件流 does.

HttpClient 怎么样?你怎么知道在哪些情况下它会起作用,在哪些情况下不会

Answer: The HttpClient 的参考源似乎表明HttpClient没有终结器。因此,它将被简单地收集。

好吧,现在一些实际的背景信息。我经常将某些 IDisposable 存储为字段,强制我的类实现 IDisposable。最终用户应该使用 using。但如果这没有发生怎么办?

Answer:如果您忘记/没有打电话IDisposable.Dispose()关于实现的对象IDisposable,一旦对象符合收集条件,我在这里所说的有关终结器的所有内容仍然会发生。除此之外,不会发生什么特别的事情。对象是否实现IDisposable或不与垃圾收集过程无关,只有终结器的存在才有。

GC 之前是否只是不必要的内存?或者你突然内存泄漏

Answer:从这个简单的信息中无法确定。这取决于什么Dispose方法就可以了。例如,如果对象已在某处注册了自身,以便在某处存在对它的引用,则某些停止使用该对象的代码实际上可能不会使该对象符合收集条件。这Dispose方法可能负责取消注册它,删除对它的最后一个引用。所以这个要看对象。仅仅因为该对象实现了IDisposable不会造成内存泄漏。如果删除了对该对象的最后一个引用,则该对象将符合收集条件,并将在未来的收集周期中被收集。


Remarks:

  • Note that the above text is also probably simplified. A full collection cycle to actually "collect memory" is probably not done on application termination as there is no point. The operating system will free the memory allocated by the process when it terminates anyway. When an application terminates, .NET Framework makes every reasonable effort to call finalizers for objects that haven't yet been garbage collected, unless such cleanup has been suppressed (by a call to the library method GC.SuppressFinalize, for example). .NET 5 (including .NET Core) and later versions don't call finalizers as part of application termination.1 (I have no additional knowledge one way or another what kind of optimizations is done here)

  • 这里更重要的部分是您需要区分内存(或其他)泄漏during程序执行和after程序执行

    • 当进程终止时,操作系统将回收分配给它的所有内存,它将关闭所有句柄(这可能会保持套接字、文件等打开),所有线程将被终止。简而言之,程序被完全从内存中删除
    • 不过,这个过程可能会留下一些花絮,它们是not除非进程事先小心地这样做了,否则会被清理。如上所述,打开的文件被关闭,但它可能尚未完全写入,因此可能以某种方式损坏。
    • 在程序执行期间,泄漏可能会使程序在分配的内存方面增长,它可能会分配太多句柄,因为它无法关闭不再需要的句柄,等等,这对于处理而言很重要IDisposable和终结器正确,但是当进程终止时,这不再是问题。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

C# 应用程序退出时会自动释放托管资源吗? 的相关文章

  • 通过 CMIS (dotCMIS) 连接到 SP2010:异常未经授权

    我正在使用 dotCMIS 并且想要简单连接到我的 SP2010 服务器 我尝试用 C 来做到这一点 如下所示http chemistry apache org dotnet getting started with dotcmis htm
  • 用于检查类是否具有运算符/成员的 C++ 类型特征[重复]

    这个问题在这里已经有答案了 可能的重复 是否可以编写一个 C 模板来检查函数是否存在 https stackoverflow com questions 257288 is it possible to write a c template
  • Asp.NET WebApi 中类似文件名称的路由

    是否可以在 ASP NET Web API 路由配置中添加一条路由 以允许处理看起来有点像文件名的 URL 我尝试添加以下条目WebApiConfig Register 但这不起作用 使用 URIapi foo 0de7ebfa 3a55
  • 使用实体框架模型输入安全密钥

    这是我今天的完美想法 Entity Framework 中的强类型 ID 动机 比较 ModelTypeA ID 和 ModelTypeB ID 总是 至少几乎 错误 为什么编译时不处理它 如果您使用每个请求示例 DbContext 那么很
  • 如何使用 ICU 解析汉字数字字符?

    我正在编写一个使用 ICU 来解析由汉字数字字符组成的 Unicode 字符串的函数 并希望返回该字符串的整数值 五 gt 5 三十一 gt 31 五千九百七十二 gt 5972 我将区域设置设置为 Locale getJapan 并使用
  • 用于登录 .NET 的堆栈跟踪

    我编写了一个 logger exceptionfactory 模块 它使用 System Diagnostics StackTrace 从调用方法及其声明类型中获取属性 但我注意到 如果我在 Visual Studio 之外以发布模式运行代
  • 如何从 appsettings.json 文件中的对象数组读取值

    我的 appsettings json 文件 StudentBirthdays Anne 01 11 2000 Peter 29 07 2001 Jane 15 10 2001 John Not Mentioned 我有一个单独的配置类 p
  • C#中如何移动PictureBox?

    我已经使用此代码来移动图片框pictureBox MouseMove event pictureBox Location new System Drawing Point e Location 但是当我尝试执行时 图片框闪烁并且无法识别确切
  • C++ OpenSSL 导出私钥

    到目前为止 我成功地使用了 SSL 但遇到了令人困惑的障碍 我生成了 RSA 密钥对 之前使用 PEM write bio RSAPrivateKey 来导出它们 然而 手册页声称该格式已经过时 实际上它看起来与通常的 PEM 格式不同 相
  • 重载<<的返回值

    include
  • 如何在整个 ASP .NET MVC 应用程序中需要授权

    我创建的应用程序中 除了启用登录的操作之外的每个操作都应该超出未登录用户的限制 我应该添加 Authorize 每个班级标题前的注释 像这儿 namespace WebApplication2 Controllers Authorize p
  • 如何在 C 中调用采用匿名结构的函数?

    如何在 C 中调用采用匿名结构的函数 比如这个函数 void func struct int x p printf i n p x 当提供原型的函数声明在范围内时 调用该函数的参数必须具有与原型中声明的类型兼容的类型 其中 兼容 具有标准定
  • 垃圾收集器是否在单独的进程中运行?

    垃圾收集器是否在单独的进程中启动 例如 如果我们尝试测量某段代码所花费的进程时间 并且在此期间垃圾收集器开始收集 它会在新进程上启动还是在同一进程中启动 它的工作原理如下吗 Code Process 1 gt Garbage Collect
  • 使用 x509 证书签署 json 文档或字符串

    如何使用 x509 证书签署 json 文档或字符串 public static void fund string filePath C Users VIKAS Desktop Data xml Read the file XmlDocum
  • 对现有视频添加水印

    我正在寻找一种用 C 在视频上加水印的方法 就像在上面写文字一样 图片或文字标签 我该怎么做 谢谢 您可以使用 Nreco 视频转换器 代码看起来像 NReco VideoConverter FFMpegConverter wrap new
  • 为什么编译时浮点计算可能不会得到与运行时计算相同的结果?

    In the speaker mentioned Compile time floating point calculations might not have the same results as runtime calculation
  • cmake 将标头包含到每个源文件中

    其实我有一个简单的问题 但找不到答案 也许你可以给我指一个副本 所以 问题是 是否可以告诉 cmake 指示编译器在每个源文件的开头自动包含一些头文件 这样就不需要放置 include foo h 了 谢谢 CMake 没有针对此特定用例的
  • 如何在Xamarin中删除ViewTreeObserver?

    假设我需要获取并设置视图的高度 在 Android 中 众所周知 只有在绘制视图之后才能获取视图高度 如果您使用 Java 有很多答案 最著名的方法之一如下 取自这个答案 https stackoverflow com a 24035591
  • C# 模拟VolumeMute按下

    我得到以下代码来模拟音量静音按键 DllImport coredll dll SetLastError true static extern void keybd event byte bVk byte bScan int dwFlags
  • IEnumreable 动态和 lambda

    我想在 a 上使用 lambda 表达式IEnumerable

随机推荐

  • 用于最小化其他应用程序的批处理文件

    我怎样才能有一个打开应用程序的bat文件 让我们称之为firefox exe 我如何调用bat文件或任何其他脚本 即vbs 来最小化应用程序 即firefox exe 然后在一两分钟后关闭它 请注意start min不起作用 下面是我的脚本
  • 如何在 Vaadin 8 中添加验证器?

    在 Vaadin 7 中有一个 addValidator 函数 但在 Vaadin 8 中它不存在 Vaadin 7 示例 TextField user new TextField User user setRequired true us
  • 使用 THREE.OBJLoader 渲染 OBJ 文件

    如何使用 THREE OBJLoader 方法渲染 OBJ 文件 我有一个示例 OBJ 格式 但它不会渲染任何内容 也不会在 chrome 开发工具中看到错误 查看 OBJLoader 使用示例 https github com mrdoo
  • 在 ncurses 中实现文本滚动的推荐方法是什么?

    我正在尝试实现一个 ncurses 应用程序 其文本滚动效果如下 推荐的方法是什么 这是我所知道的 您可以使用scroll将文本缓冲区向上或向下移动 1 行 但是 如果向下滚动 您最终会在顶部出现一个空行 如果向上滚动 则会在底部出现一个空
  • C++ 将十六进制字符串转换为有符号整数

    我想在 C 中将十六进制字符串转换为 32 位有符号整数 例如 我有十六进制字符串 fffefffe 其二进制表示形式为 11111111111111101111111111111110 其有符号整数表示形式为 65538 我如何在 C 中
  • 如何将 groupby() 和 value_counts() 转换为多个饼图/条形图

    假设我有一个数据框 并且正在查看其中的 2 列 2 个系列 使用其中一列 no employees 下面 有人可以帮我弄清楚如何创建 6 个不同的饼图或条形图 每个 no employees 分组 1 个 来说明处理列中 是 否 值的值计数
  • C++程序需要文件关联

    我正在分发一个免费软件产品 该产品可以读取和写入具有唯一扩展名的文本文件 我希望双击这样的文件会自动启动该应用程序 在 Windows 7 Professional 上进行开发时 我设置了一个关联 以便在双击时打开文件 方法是右键单击文件
  • 奇怪的UTF8字符串比较

    我在 UTF8 字符串比较方面遇到了这个问题 我真的不知道 它开始让我头疼 请帮帮我 基本上我有一个来自 UTF8 编码的 xml 文档的字符串 Mina Tidigare anst llningar 当我将该字符串与我自己输入的完全相同的
  • 如何改进印地语文本提取?

    我正在尝试从 PDF 中提取印地语文本 我尝试了所有从 PDF 中提取内容的方法 但都不起作用 有解释为什么它不起作用 但没有答案 所以 我决定将PDF转换为图像 然后使用pytesseract提取文本 我已经下载了印地语训练数据 但这也给
  • MySQL 类型=MyISAM 错误

    本月早些时候 我正在开发我的论坛网站 遇到了一个小问题 不幸的是 除了我的数据库之外 一切都很顺利 我在里面做了一张桌子 叫做users用这个脚本 CREATE TABLE users id int 4 NOT NULL auto incr
  • 如何在文本文件中搜索字符串?

    我想检查字符串是否在文本文件中 如果是 则执行 X 如果不是 则执行 Y 但是 此代码始终返回True因为某些原因 任何人都可以看到出了什么问题吗 def check datafile file example txt found Fals
  • 将线程本地内存刷新到全局内存意味着什么?

    我知道Java中易失性变量的目的是对此类变量的写入对其他线程立即可见 我还知道同步块的作用之一是将线程局部内存刷新到全局内存 我从未完全理解在这种情况下对 线程本地 内存的引用 我知道仅存在于堆栈上的数据是线程本地的 但是当谈论堆上的对象时
  • CSS 网格包裹

    是否可以在不使用媒体查询的情况下制作 CSS 网格换行 就我而言 我想要将不确定数量的项目放置在网格中 并且希望该网格进行换行 使用 Flexbox 我无法可靠地很好地间隔事物 我也想避免一堆媒体查询 Here s 一些示例代码 grid
  • 使用 ITextRenderer 从包含非拉丁字符的 HTML 生成 PDF 不起作用

    这是我调查的第二天 没有任何结果 至少现在 我可以问一些非常具体的问题 我正在尝试编写一个有效的 HTML 代码 其中包含 PDF 文件中的一些非拉丁字符iText更具体地使用文本渲染器 from 飞碟 我的简短示例 代码首先使用以下值初始
  • 为什么多个 javascript 库将 $ 用于一种或另一种用途

    我见过几个使用 的 javascript 库 无论是 jQuery mootools prototype 等 甚至一些关于 javascript 的书籍也建议使用 作为 document getElementById 的函数替换 这只是随机
  • Python 请求发布文件

    使用 CURL 我可以发布一个文件 例如 CURL X POST d pxeconfig cat boot txt https ip 8443 tftp syslinux 我的文件看起来像 cat boot txt line 1 line
  • 如何在 iOS 6 中为文本添加下划线?

    我正在尝试在标签中的某些文本下划线 但是 我不知道如何获取标签中整个文本的范围 这是我到目前为止所拥有的 NSMutableAttributedString mat self tableLabel attributedText mutabl
  • 哪个 C# 定时器?

    我正在编写一个包含计时器的类 最重要的是 它可能不会在 0 处初始化 它可能已经开始计时 并且该类将包含 Start Pause Resume 和 Stop Complete 方法 我知道我可以使用 C 中的许多计时器 即 System T
  • Mac OS 10.5 上的 Java 1.6 SDK

    适用于 Mac 的 Java 1 6 SDK 已发布吗 我好像找不到 是的 但仅适用于基于 Intel 的 64 位 Mac 即使用 Core 2 双核或单核 或 Xeon 芯片的 Mac 不支持原装Core芯片 也不支持任何PPC芯片 此
  • C# 应用程序退出时会自动释放托管资源吗?

    我完全知道 using 语句是处理的方式IDisposables 请不要在评论中重复此建议 当 C NET 4 5 或更高版本 应用程序关闭时 会发生什么IDisposable哪些没有得到妥善处置 我知道有些有一个用于处理非托管资源的终结器