托管 (.net) 应用程序中内存泄漏的最常见(且经常被忽视)的原因是什么?

2024-01-29

请任何人推荐一个快速清单/最佳实践指南,以帮助我们避免可能导致 .net 应用程序内存泄漏的简单(但微妙)错误

当我处于项目的测试阶段时,我发现开始寻找内存泄漏的原因非常困难且相当痛苦。

如果有“经验法则”可以完全指导托管应用程序中的内存泄漏,我恳求您分享您的经验。

Thanks.

(我认为托管应用程序应该是“内存管理”,即 GC?那么为什么我们仍然在纯托管代码中发现泄漏?)


泄漏有多种形式:

  • 非托管泄漏(分配非托管代码的代码)
  • 资源泄漏(分配和使用非托管资源的代码,如文件、套接字)
  • 延长对象的生命周期
  • 对 GC 和 .NET 内存管理工作原理的错误理解
  • .NET 运行时中的错误

前两个通常由两段不同的代码处理:

  • 在对象上实现 IDisposable 并在 Dispose 方法中处置非托管内存/资源
  • 实现终结器,以确保当 GC 发现对象符合回收条件时释放非托管资源

然而,第三个则不同。

假设您正在使用一个包含数千个对象的大列表,总共占用了大量内存。如果您保留对此列表的引用的时间超过了需要的时间,就会出现看起来像内存泄漏的情况。此外,如果您不断向此列表添加内容,使其定期随着更多数据而增长,并且旧数据永远不会被重用,那么您肯定会出现内存泄漏。

我经常看到的这种情况的根源之一是将方法附加到事件处理程序,但在完成后忘记取消注册它们,从而导致事件处理程序的大小和要执行的代码慢慢膨胀。

第四,对 .NET 内存管理工作原理的错误理解可能意味着您在进程查看器中查看内存使用情况,并注意到您的应用程序的内存使用量不断增长。如果您有大量可用内存,GC 可能不会经常运行,从而给您提供错误的当前内存图usage内存,而不是映射内存。

第五,这更难,到目前为止,我只在 .NET 中看到了一个资源管理错误,据我所知,它已计划在 .NET 4.0 中修复,它是将桌面屏幕复制到 .NET 映像中。


Edit:针对评论中的问题,如何避免保留引用时间超过必要的时间,那么唯一的方法就是这样做。

让我解释。

首先,如果您有一个长时间运行的方法(例如,它可能正在处理磁盘上的文件,或下载某些内容,或类似的),并且您在该方法的早期(在长期运行之前)使用了对大数据结构的引用。运行部分,然后您不对该方法的其余部分使用该数据结构,然后 .NET 在发布版本中(并且不在调试器下运行)足够聪明,可以知道此引用,尽管它保存在从技术上讲,在范围内的变量有资格进行垃圾收集。垃圾收集器在这方面确实非常积极。在调试构建和在调试器下运行时,它将在方法的生命周期内保留引用,以防您想在断点处停止时检查它。

但是,如果引用存储在声明该方法的类中的字段引用中,则不太聪明,因为无法确定稍后是否会重用它,或者至少非常非常困难。如果这个数据结构变得不必要,你应该清除你持有的引用,以便 GC 稍后会拾取它。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

托管 (.net) 应用程序中内存泄漏的最常见(且经常被忽视)的原因是什么? 的相关文章

  • MVVM ViewModel 很多属性

    我是 MVVM 新手 正在开发一个应用程序 我有一个包含很多属性的表单视图 大约 50 个 我不能将它们分离到用户控件中 因为这会破坏 mvvm 原则 我无法将它们分成模型 因为它们包含逻辑 属性更改 错误更改这些都不是 poco 类 并且
  • 使用 LINQ 迭代类属性

    有一个 ParsedTemplate 类 它有超过 300 个属性 类型为 Details 和 BlockDetails parsedTemplate 对象将由函数填充 填充这个对象后 我需要一个 LINQ 或其他方式 来查找是否有任何属性
  • 将浮点型转换为双精度型

    我正在尝试转换Single to Double同时保持原来的价值 我找到了以下方法 Single f 5 2F Double d1 f 5 19999980926514 Double d2 Double Parse f ToString 5
  • 执行鼠标单击而不移动光标

    除了移动光标之外 我找不到任何解决方案Cursor类 点击mouse event然后将光标移动到原来的位置 我正在玩SendInput现在可以运行 但仍然没有机会找到好的解决方案 有什么建议吗 您应该使用 Win32 API 使用 user
  • 将数组复制到动态分配的内存

    我的代码可以正常工作 但我觉得好像有一种更快的方法可以做到这一点 特别是在我的函数副本中 这是我的代码 这能再快一点吗 顺便说一句 这是 C 语言 另外 当我从函数返回 cpy 时 它是否会删除动态内存 因为它超出了范围 我不想发生内存泄漏
  • 如何获取 ASP.NET MVC 中当前的虚拟路径?

    如何从 ASP NET MVC 视图中获取当前路径 URL 如果没有办法将其获取到视图中 那么如何将其获取到控制器中以便将其传递到视图呢 EDIT 我不需要 url 的协议和主机部分 这将为您返回视图中的 url
  • 有没有办法在 C# 中仅通过文件名查找文件?

    我们现在使用绝对路径或相对路径在 C 应用程序中查找文件 如果文件位于当前工作目录下或 路径 之一下 有没有办法仅通过名称查找文件 使用绝对路径不好 使用相对路径也不够好 因为我们可能通过重命名或移动项目文件夹来更改项目结构 如果我们的代码
  • ASP.NET 3.5 更新至 4.0 -> Sys.WebForms.PageRequestManager 未定义

    正如标题所示 我最近将包含 UpdatePanels 和类似 AJAX 技术的 ASP NET 3 5 应用程序更新为 ASP NET 4 0 不幸的是 UpdatePanel 不再起作用 整页回发使一切都变得糟糕 Web config 文
  • 用eclipse测试java程序的内存消耗[关闭]

    就目前情况而言 这个问题不太适合我们的问答形式 我们希望答案得到事实 参考资料或专业知识的支持 但这个问题可能会引发辩论 争论 民意调查或扩展讨论 如果您觉得这个问题可以改进并可能重新开放 访问帮助中心 help reopen questi
  • 用户如何在winforms运行时调整控件大小

    假设我有一个图片框 现在我想要的是用户应该能够随意调整图片框的大小 但是我不知道如何开始做这件事 我搜索过互联网 但信息很少 有人至少可以指导我从哪里开始吗 这很容易做到 Windows 中的每个窗口都具有与生俱来的可调整大小的能力 它刚刚
  • 实现“LazyProperty”类 - 这是一个好主意吗?

    我经常发现自己编写的属性是惰性评估的 就像是 if backingField null backingField SomeOperation return backingField 代码不多 但如果您有很多属性 它确实会重复很多次 我正在考
  • .NET Framework 2.0 Service Pack 1 中新增的类型

    我以为 NET 2 0 SP1 中只有错误修复 没有新类型 直到我遇到few http davesbox com archive 2008 08 25 new for visual studio 2008 sp1 and fxcop 1 3
  • WPF DataGrid 排序后滚动到顶部

    我有一个使用数据网格的 Net 4 0 WPF 应用程序 目前 按列排序后 网格的滚动位置保持在排序前的位置 对于此应用程序 我需要在任何排序后滚动到网格顶部 我尝试过像这样处理排序事件 Private Sub myDataGrid Sor
  • .NET 中的错误和异常有什么区别?

    您能向我解释一下错误和异常之间的区别吗 一个例外是利用语言语义的类 正如其他人所说 异常会中断堆栈的执行 直到被捕获 一个例外can用于传达错误 但更一般地用于传达发生了异常情况 另一方面 错误可能是异常的 也可能不是异常的 错误有以下几种
  • 从 DataGridViewSelectedRowCollection 复制列详细信息

    我有一个 DataGridView 它绑定到一个由设计时未知的 SQL 查询返回的 DataSet 好吧 我知道查询是什么 我只是不知道用户选择了哪一个 我允许用户从表中选择一组行并单击 确定 按钮 然后我想将这些行复制到新的 DataGr
  • C++/CLI 中的 Lambda 表达式

    如何在 C CLI 中使用 lambda 表达式 在 C 中 lambda 实际上只是用于创建委托的语法糖 C CLI支持代表 http www functionx com cppcli classes Lesson15c htm 因此您仍
  • 与常规 SQL 查询不同,为什么“linq to sql”查询以 FROM 关键字开头?

    为什么 linq to sql 查询以FROM与常规 SQL 查询不同的关键字 LINQ 模仿Logical Query processing在 SQL 中你有 8 SELECT 9 DISTINCT 11 TOP 1 FROM 2 ON
  • 如何在Entity Framework 5中正确触发集合的延迟加载?

    我在我的应用程序中使用 EF5 代码优先 我有一个包含一些延迟加载字段的表 public class TestEntity public int Id get set public virtual TestEntity2 SubEntity
  • 正则表达式获取模式的最后一次出现

    我有一个字符串 我需要选择最后一次出现的模式 该字符串是 1302638400000 0 0 1302724800000 0 610 64999999999998 1302811200000 0 2266 6500000000001 130
  • 打印“X”个字符数与“X”字符串长度的所有可能组合(暴力破解)

    我正在尝试编写一个单词组合生成器 我的意思是打印 X 个字符数与 X 字符串长度的所有可能组合 首先 我需要说的是 我在 StackOverFlow 中看到了一个关于这个问题的问题 其中有很多单词生成器的答案来执行此操作 在不同的语言上 但

随机推荐

  • 我们如何知道调用者函数的名称?

    在C语言中 FUNCTION 可以用来得到current函数的名称 但是如果我定义一个名为 a 的函数 并在 b 中调用它 如下所示 b a 现在 在源代码中 有很多像 b 这样的函数调用 a 例如c d e 是否可以在 a 中添加一些代码
  • 使用列名从 ResultSet 获取小写列

    我使用的是 Oracle 12cr1 数据库 看来我无法从中获得价值ResultSet如果列名是小写 则使用列名 创建表create table Tab col number col varchar2 10 所以第二列是小写的 如果我打电话
  • FILE_FLAG_DELETE_ON_CLOSE 和内存映射文件

    并不是说它特别有用 但我很好奇为什么下面的方法有效 仅仅是因为即使文件被删除后该页面仍然在内存中吗 在什么情况下 如果页面被换出 数据会丢失 include
  • 链接 gcc 6、gcc 7 和 gcc 8 对象安全吗?

    链接 C 17 C 14 和 C 11 对象是否安全 https stackoverflow com q 46746878 2069064询问有关链接使用不同语言标准编译的对象的问题 Jonathan Wakely 对这个问题的出色回答解释
  • 从批处理文件中发现Java安装在哪里?

    我想从批处理脚本设置 JAVA HOME 变量 此代码片段将在当前路径中搜索 java exe 并打印出找到它的位置 for f j in java exe do echo dp PATH j 在我的系统上这给了我 C WINDOWS sy
  • 错误 ASP 0177:8007007e COM DLL CreateObject 失败

    我们一直在尝试在新服务器上安装 COM DLL 界面是经典的 ASP 地图连接器 DLL 似乎是问题所在 但据我所知 这是问题所在 我们无法获取 IIS 提供的页面 只给出 500 错误 跟踪 ASP 时 127 ASP SCRIPT TR
  • 给 Jekyll 类别添加标题

    我想将我的帖子的打印类别名称转换为标题大小写 我找不到合适的液体过滤器 我尝试使用破折号和驼峰过滤器 但没有骰子 或者 我想打印 YAML frontmatter 中写入的类别名称 例如 对于包含以下内容的帖子 category Here
  • Android 中的计时器不会停止

    我在android中做了一个应用程序并使用了这样的计时器 try CountDownTimer start1 new CountDownTimer 20000 1000 public void onTick long millisUntil
  • CAGradientLayer 不起作用[重复]

    这个问题在这里已经有答案了 我创建了一个新项目 在LinkedIn中QuartzCore framework并进口
  • 如何阻止浏览器对 GET 上的表单值进行 url 编码

    我有一个表格method get 在表单中 我需要传递 CSS 文件的 URL 但它正在将其编码为http 3A 2F 2Fwww etc 有没有办法停止 URL 编码 因为它会破坏文件 Thanks 背景 It s a bit more
  • 为什么背景颜色需要 1px 粗体? [复制]

    这个问题在这里已经有答案了 这是我的粗话 table orders background color ff0000 然而 当我实际运行这个时 我收到一条错误消息Invalid CSS after ff0000 expected expres
  • OpenCV - 找不到指定扩展名的编码器

    这是我用来将 IplImage 转换为 jpg 的代码 IplImage fIplImageHeader fIplImageHeader cvCreateImageHeader cvSize 160 120 8 3 fIplImageHea
  • ios - 应用程序关闭时本地通知不更新徽章号码

    我注意到 当 iOS 设备中收到本地通知时 通知会显示在通知中心 但应用程序关闭时应用程序徽章编号不会更新 我需要点击通知中心的通知才能将本地推送消息传输到应用程序 这是正常行为吗 可以通过远程推送通知来解决这个问题吗 您可以利用appli
  • Iframe.readyState 在 Chrome 中不起作用

    我动态创建一个 Iframe 并将下载页面设置为 url二进制文件 xls doc 下载文件时我会显示动画 当没有的时候 我就把它隐藏起来 问题是 Chrome 不知道文件何时完全下载 即 iframe 何时完全加载 我使用 iframe
  • 处理 JavaScript 中的特定错误(考虑异常)

    您将如何实现不同类型的错误 以便能够捕获特定的错误并让其他错误出现 实现此目的的一种方法是修改Error object Error prototype sender function throwSpecificError var e new
  • XCode/MonoMac 中的自定义控件等效项

    我是一名 NET 开发人员 正在尝试 Windows 应用程序的 OSX 端口 我正在使用 MonoDevelop 和 MonoMac 带有 XCode Interface Builder 来创建我的 UI 来自 Windows 我试图理解
  • 更改多个音轨视频的音频

    我有带有多个音轨的视频 我想播放视频并希望更改视频中的音轨 有什么方法可以在 html 中制作这个 或者有 html 支持的播放器吗 您应该使用 Hermes 建议的答案 var video document getElementById
  • 如何访问 .gdbinit 和 gdb 本身内部的环境变量?

    我希望在使用 gdb 进行调试时设置源代码的路径 我选择使用 gdbinit 文件来完成此操作 基本上 它包含一个命令 directory path to src 但是 我希望能够将该命令指定为 directory SOURCESROOT
  • java 2d 中的选取

    我正在使用 java2d 绘制一个简单的图形 目前我已经通过为每个对象 形状调用 contains MousePoint 来实现拾取 这可以工作 但可以线性缩放 java2d中有没有更有效的拾取方法 是的 尽管完整的答案对于这个空间来说太长
  • 托管 (.net) 应用程序中内存泄漏的最常见(且经常被忽视)的原因是什么?

    请任何人推荐一个快速清单 最佳实践指南 以帮助我们避免可能导致 net 应用程序内存泄漏的简单 但微妙 错误 当我处于项目的测试阶段时 我发现开始寻找内存泄漏的原因非常困难且相当痛苦 如果有 经验法则 可以完全指导托管应用程序中的内存泄漏