托管 (.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) 应用程序中内存泄漏的最常见(且经常被忽视)的原因是什么? 的相关文章

  • 解决找不到程序集的问题 |文件未找到异常 |融合日志

    我正在尝试将我的解决方案包 wsp 部署到 SharePoint 2007 环境 WSP 包含一个功能 该功能加载功能接收器类以在运行时部署计时器作业 在部署此 WSP 时 我不断得到 特征 fb631f6c 2c46 4ab5 b7b3
  • 如何让 LinqToSql 将“索引提示”传递给 sql server?

    由于我们不能相信我们的客户会更新 sql server 中的索引统计信息等 因此我们过去不得不使用索引提示 http www sql server performance com tips hints general p1 aspx 由于我
  • 在 .Net 托管的 IronPython 脚本中设置和获取变量

    我正在尝试使用 Net 控制台应用程序中托管的 IronPython 来构建验证规则引擎的原型 我已经将脚本精简到我认为的基础内容 var engine Python CreateEngine engine Execute from Sys
  • 删除指向对象的 C++ 指针

    我认为删除命令会释放我分配的内存 有人可以解释为什么删除后我似乎仍然有内存在使用吗 class Test public int time int main Test e e new Test e gt time 1 cout lt lt e
  • 同一服务器上的多个.NET版本

    所以我一直都知道在一台计算机 客户端或服务器 上运行多个版本的 NET 框架是可以的 这个问题 https stackoverflow com questions 407306 running many versions of net on
  • CompileAssemblyFromDom 抛出访问被拒绝异常

    代码 using var codeProvider new CSharpCodeProvider var compilerParameter new CompilerParameters assemblies assemblyName fa
  • 枚举扩展方法

    在vs2008中 是否可以编写适用于任何枚举的扩展方法 我知道您可以针对特定枚举编写扩展方法 但我希望能够使用单个扩展方法对每个枚举进行处理 这可能吗 是的 只需针对基础进行编码Enum类型 例如 public static void So
  • 从 mvc 控制器使用 Web api 控制器操作

    我有两个控制器 一个mvc控制器和一个api控制器 它们都在同一个项目中 HomeController Controller DataController ApiController 如果我想从 HomeController 中使用 Dat
  • HttpWebRequest/HttpResponse:如何在响应中发送数据?

    我有一个客户端和一个服务器 在客户端我有 HttpWebRequest request HttpWebRequest WebRequest Create http localhost fa Default aspx request Meth
  • SQLite .NET 性能,如何加快速度?

    在我的系统上 约 86000 个 SQLite 插入需要长达 20 分钟 意味着每秒约 70 个插入 我要做数百万 我怎样才能加快速度 对每一行的 SQLiteConnection 对象调用 Open 和 Close 会降低性能吗 交易有帮
  • 如何在完成之前从 ReplaySubject 获取最新值

    我需要一种方法来获取添加到 ReplaySubject 中符合特定条件的最新项目 下面的示例代码完成了我需要它做的事情 但感觉不是正确的方法 static void Main string args var o new ReplaySubj
  • 什么时候值得使用 BindingSource?

    我想我非常了解 BindingSource 类的作用 即在数据源和 UI 控件之间提供一个间接层 它实现了 IBindingList 接口 因此还提供了对排序的支持 而且我已经经常使用它 没有太多问题 但我想知道我使用它的频率是否超过了应有
  • 没有强命名的代码签名是否会让您的应用程序容易被滥用?

    尝试了解authenticode代码签名和强命名 我是否正确地认为 如果我对引用一些 dll 非强命名 的 exe 进行代码签名 恶意用户就可以替换我的 DLL 并以看似由我签名但正在运行的方式分发应用程序他们的代码 假设这是真的 那么您似
  • 用于登录 .NET 的堆栈跟踪

    我编写了一个 logger exceptionfactory 模块 它使用 System Diagnostics StackTrace 从调用方法及其声明类型中获取属性 但我注意到 如果我在 Visual Studio 之外以发布模式运行代
  • WCF 中 SOAP 消息的数字签名

    我在 4 0 中有一个 WCF 服务 我需要向 SOAP 响应添加数字签名 我不太确定实际上应该如何完成 我相信响应应该类似于下面的链接中显示的内容 https spaces internet2 edu display ISWG Signe
  • 控件的命名约定[重复]

    这个问题在这里已经有答案了 Microsoft 在其网站上提供了命名指南 here http msdn microsoft com en us library xzf533w0 VS 71 aspx 我还有 框架设计指南 一书 我找不到有关
  • 垃圾收集器是否在单独的进程中运行?

    垃圾收集器是否在单独的进程中启动 例如 如果我们尝试测量某段代码所花费的进程时间 并且在此期间垃圾收集器开始收集 它会在新进程上启动还是在同一进程中启动 它的工作原理如下吗 Code Process 1 gt Garbage Collect
  • C# - OutOfMemoryException 在 JSON 文件上保存列表

    我正在尝试保存压力图的流数据 基本上我有一个压力矩阵定义为 double pressureMatrix new double e Data GetLength 0 e Data GetLength 1 基本上 我得到了其中之一pressur
  • 如何防止用户控件表单在 C# 中处理键盘输入(箭头键)

    我的用户控件包含其他可以选择的控件 我想实现使用箭头键导航子控件的方法 问题是家长控制拦截箭头键并使用它来滚动其视图什么是我想避免的事情 我想自己解决控制内容的导航问题 我如何控制由箭头键引起的标准行为 提前致谢 MTH 这通常是通过重写
  • 使用.NET技术录制屏幕视频[关闭]

    Closed 这个问题正在寻求书籍 工具 软件库等的推荐 不满足堆栈溢出指南 help closed questions 目前不接受答案 有没有一种方法可以使用 NET 技术来录制屏幕 无论是桌面还是窗口 我的目标是免费的 我喜欢小型 低

随机推荐

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

    在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 应用程序内存泄漏的简单 但微妙 错误 当我处于项目的测试阶段时 我发现开始寻找内存泄漏的原因非常困难且相当痛苦 如果有 经验法则 可以完全指导托管应用程序中的内存泄漏