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# 应用程序退出时会自动释放托管资源吗? 的相关文章

  • C# 方法重载决策不选择具体的泛型覆盖

    这个完整的 C 程序说明了这个问题 public abstract class Executor
  • 前向声明类型和“已声明为类类型的非类类型”

    我对以下代码有问题 template
  • MVC3中设置下拉列表中的所选项目

    我必须为视图中的下拉列表设置所选项目 但它不起作用 View div class editor label Html LabelFor model gt model Gender div div class editor field Htm
  • 当事件button.click发生时,如何获取按钮名称/标签?

    我以编程方式制作按钮并将它们添加到堆栈面板中 以便每次用户导航到页面时按钮都会发生变化 我正在尝试做这样的事情 当我单击创建的按钮时 它将获取按钮的标签并转到正确的页面 但是 我无法使用 RoutedEventHandler 访问按钮元素
  • extern 声明和函数定义都在同一文件中

    我只是浏览了一下gcc源文件 在gcc c 我发现了类似的东西 extern int main int char int main int argc char argv 现在我的疑问是extern是告诉编译器特定的函数不在这个文件中 但可以
  • 强制初始化模板类的静态数据成员

    关于模板类的静态数据成员未初始化存在一些问题 不幸的是 这些都没有能够帮助我解决我的具体问题的答案 我有一个模板类 它有一个静态数据成员 必须为特定类型显式实例化 即必须专门化 如果不是这种情况 使用不同的模板函数应该会导致链接器错误 这是
  • 如何使用 ASP.NET Core 获取其他用户的声明

    我仍在学习 ASP NET Core 的身份 我正在进行基于声明的令牌授权 大多数示例都是关于 当前 登录用户的 就我而言 我的 RPC 服务正在接收身份数据库中某个用户的用户名和密码 我需要 验证是否存在具有此类凭据的用户 获取该用户的所
  • C++中判断unicode字符是全角还是半角

    我正在编写一个终端 控制台 应用程序 该应用程序应该包装任意 unicode 文本 终端通常使用等宽 固定宽度 字体 因此要换行文本 只需计算字符数并观察单词是否适合一行并采取相应的操作 问题是 Unicode 表中的全角字符在终端中占用了
  • 在 VS 中运行时如何查看 C# 控制台程序的输出?

    我刚刚编写了一个名为 helloworld 的聪明程序 它是一个 C NET 4 5 控制台应用程序 在扭曲的嵌套逻辑迷宫深处 使用了 Console WriteLine 当我在命令行运行它时 它会运行并且我会看到输出 我可以执行其他命令并
  • 从网页运行 ClickOnce 应用程序,无需用户操作

    我们有一个基于 Java 的 Web 应用程序以及用 C 编写的相同应用程序 如果 java 检查器发现客户端计算机上没有安装 Java 则应该运行该应用程序 这个想法是运行 C 单击一次 http en wikipedia org wik
  • 从 C# 使用 Odbc 调用 Oracle 包函数

    我在 Oracle 包中定义了一个函数 CREATE OR REPLACE PACKAGE BODY TESTUSER TESTPKG as FUNCTION testfunc n IN NUMBER RETURN NUMBER as be
  • 模板外部链接?谁能解释一下吗?

    模板名称具有链接 3 5 非成员函数模板可以有内部链接 任何其他模板名称应具有外部链接 从具有内部链接的模板生成的实体与在其他翻译单元中生成的所有实体不同 我知道使用关键字的外部链接 extern C EX extern C templat
  • 如何在 C# 中创建异步方法?

    我读过的每一篇博客文章都会告诉您如何在 C 中使用异步方法 但由于某些奇怪的原因 从未解释如何构建您自己的异步方法来使用 所以我现在有这段代码使用我的方法 private async void button1 Click object se
  • 比较:接口方法、虚方法、抽象方法

    它们各自的优点和缺点是什么 接口方法 虚拟方法 抽象方法 什么时候应该选择什么 做出这一决定时应牢记哪些要点 虚拟和抽象几乎是一样的 虚方法在基类中有一个实现 可以选择重写 而抽象方法则没有 并且must在子类中被覆盖 否则它们是相同的 在
  • 模板类的模板构造函数的 C++ 显式模板特化

    我有一个像这样的课程 template
  • 将 Lambda 表达式树与 IEnumerable 结合使用

    我一直在尝试了解有关使用 Lamba 表达式树的更多信息 因此我创建了一个简单的示例 这是代码 如果作为 C 程序粘贴到 LINQPad 中 它可以工作 void Main IEnumerable
  • 代码中的.net Access Forms身份验证“超时”值

    我正在向我的应用程序添加注销过期警报 并希望从我的代码访问我的 web config 表单身份验证 超时 值 我有什么办法可以做到这一点吗 我认为您可以从 FormsAuthentication 静态类方法中读取它 这比直接读取 web c
  • 在 Win32 控制台应用程序中设置光标位置

    如何在 Win32 控制台应用程序中设置光标位置 最好 我想避免制作句柄并使用 Windows 控制台功能 我花了整个早上沿着那条黑暗的小巷跑 它产生的问题比它解决的问题还要多 我似乎记得当我在大学时使用 stdio 做这件事相对简单 但我
  • EntityFramework 6.0.0.0 读取数据,但不插入

    我创建了一个基于服务的数据库 folderName gt Add New Item gt Data gt Service based Database文件到 WPF 应用程序中 然后我用过Database First方法并创建了Person
  • 如何在 C 中将 char 连接到 char* ?

    我怎样才能前置char c to char myChar 我有c值为 A and myChar值为 LL 我怎样才能前置c to myChar使 ALL 这应该有效 include

随机推荐

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

    我怎样才能有一个打开应用程序的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哪些没有得到妥善处置 我知道有些有一个用于处理非托管资源的终结器