小编Gar*_*rey的帖子

System.Drawing.Bitmap 中的 C# OutOfMemoryException

有没有办法在运行时获得有关 OutOfMemoryException 的更多详细信息?或者,这个异常能否以某种方式不被封闭的 try/catch 捕获,而是一个 try/catch 更高的调用堆栈?我无法使用 WinDBG 进行复制,因此它必须是我可以从应用程序登录的内容。

对于冗长的解释,我深表歉意,但有很多可能的原因需要消除,我对此进行了解释。

我已经阅读了 OutofMemoryException 的所有可能性,并基本上消除了所有这些可能性。通常,应用程序运行良好,但有时仅在某些计算机上,我会收到 OutOfMemoryException。由于这些报告在现场无法在本地重现,因此我只有日志可以查看。但我有相当多的细节。

奇怪的是:

  • 任何可能在逻辑上在附近分配内存的东西都在 try/catch 中,但异常被视为未处理(并在调用堆栈更高的地方捕获)
  • 没有使用 StringBuffers
  • 即使在重新启动并重新启动应用程序后也会发生异常。
  • 仅几分钟后就会发生异常,并且只分配了大约 30MiB 的内存,以不超过 1.5MiB 的块为单位。
  • 验证应用程序(为“任何”处理器构建)是否以 64 位运行。
  • 不缺少磁盘空间(270Gb 可用)并启用页面文件。
  • 似乎不是可能的 LoH 碎片问题。

最近在应用程序的不同部分发生了几次。第一次,我断定存在损坏的 .NET 程序集,因为异常发生在它第一次加载 System.Web.Serialization 程序集时。我可以确定它是在第一次使用该程序集的方法调用期间发生的。重新映像计算机(与原始设置相同)和更新 Windows 解决了此问题。

但是,在我看来,在几天内发生的第二种情况(不同的客户)也是腐败的可能性很小。这种情况发生在不会加载任何程序集的位置。我现在正在重新考虑第一个错误。我所知道的:

  • 它发生在线程池线程中 (System.Timers.Timer, [Statthread])
  • 少量活动线程 (< 5)
  • 它发生在下载 1MiB 文件的时间。这被读入 MemoryStream,因此它可能与 2MiB 一样大。然后将其提供给 System.Drawing.Bitmap 构造函数,从而生成大约 8MiB 的位图。然而,这一切都在捕获 System.Exception 的 try/catch 中。唯一不在 try/catch 中的是返回 byte[] 引用,它应该只是一个引用副本,而不是任何内存分配。
  • 在此之前没有进行其他重要的内存分配。在我的本地版本中查看堆,它应该以相同的方式运行,只显示应用程序图标和将在小对象堆上的几十个对象。
  • 它在具有特定输入的特定系统上是可重复的。然而,这些系统是相互克隆的。只有明显的变化是 Windows 更新的顺序。
  • 我正在运行的程序集已签名。没有校验和确保它没有损坏吗?所有系统组件都一样吗?我不明白如何通过损坏的 dll 甚至数据来解释这个实例。
  • 在异常时查看调用堆栈出奇地没有帮助。我在下面的代码中指出抛出异常的地方。
  • 有一些 COM 对象的用途。然而,在正常情况下,我们运行应用程序数周没有内存问题,当我们得到这些异常时,它们几乎立即发生,仅使用大约 20 个相对轻量级的 COM …

.net c# out-of-memory .net-4.5

5
推荐指数
1
解决办法
1884
查看次数

标签 统计

.net ×1

.net-4.5 ×1

c# ×1

out-of-memory ×1