【问题标题】:SQL Stored Proc eats memory over timeSQL 存储过程会随着时间的推移消耗内存
【发布时间】:2011-09-28 14:13:57
【问题描述】:

我一直在尝试诊断此 Web 服务中的 30 MB 内存泄漏。它使用标准存储过程从 SQL 获得了一些批量数据。每个“批量”返回大约 10,000-50,000 行。 Web 服务生成其报告并将其发送给调用者。

似乎每次您调用此报告时,都会有 30 MB 的内存被“吃掉”并且没有被释放。因此,如果您拨打相同的电话约 1,000 次,则 3 GB 系统内存不足。如果您回收应用程序池,则会释放内存。你可以在那里坐一天,内存不会被释放。所以超时后网络服务器内存不足。

我单步执行代码,分析了它,最后确定是这 3 个“批量”获取获得了适量的数据。每个取出 10 MB,完成后不归还。存储的过程很好。调用的唯一奇怪之处在于它使用 LINQ 调用存储的过程并将数据转换为 Poco 对象,使用 XML 映射文件。

我尝试更改它,以便他们每次调用存储过程时都使用新的 DataContext,然后将 DataContext 设置为 null。我尝试将所有类型的对象设置为 null,然后调用 GC.Collect,内存仍然被吃掉,直到你回收应用程序池才被释放。

我会很感激任何线索。我怀疑这与 LINQ 和大数据返回有关。

【问题讨论】:

  • 您能告诉我们您使用什么语言编写 Web 服务吗?这样我们可以更好地回答您的问题
  • C# 使用 SQL CREATE TYPE dbo.TableOfInts AS TABLE ( ID int ) 中的自定义数据类型请求数据
  • 我会研究对 Poco 对象的翻译。
  • ie webservice 填写一个DataTable,里面装满了它想要的行的Identities 整数,然后存储的proc 返回这些行。显然,这个数据表可能很大。将其设置为 null 无效。
  • 这是你的问题,将你的 datacontext 设置为 null 而不处理它只是删除了对它的引用,因此 GC 不会将它从内存中删除。记得在下面标记 Adrian 的回答,因为这就是他想要告诉你的。

标签: c# sql linq web-services memory-leaks


【解决方案1】:

这就是垃圾回收的丑陋一面:开发人员倾向于认为他们不再需要担心释放内存。但这并不完全正确!

某些类实例必须被 Disposed(在 .Net 中被调用)。事实上,每个实现IDisposable 的对象都必须由开发人员处理其内存周期。

流就是一个很好的例子。流是一次性的,它们通常携带大量数据(大于简单字符串)。想象一下每 5 秒处理一个 2KB 流的服务。这还不算多吧?例如,它是一个小型 XML。但是如果你不处理它会发生什么?当然,您可以自己计算,但我会给您结果:大约 33.7 MB 未使用的垃圾。

底线:处理掉你的一次性用品。

【讨论】:

  • 严格来说并非如此。许多对象实现了Dispose pattern,这会导致在GC 清理对象时调用Dispose。不过,依靠这个是一个糟糕的主意,所以你的答案仍然是 100% 有效的。就我个人而言,我认为这是一个错误,但是当一个对象突然间由于其引用仍在范围内而不再执行时,这是值得注意的。
  • @MongusPong 我倾向于始终管理我的对象生命周期。 GC 很棒,但它让开发人员变得懒惰。许多人现在开始工作,甚至不知道您应该管理您的 obj,这让我很伤心。我不完全信任 GC,所以我让 GC 处理小东西。 管理大事(流、数据集等)
  • 告诉我。由于缺乏开发人员意识,我花费了更多的开发人员时间来跟踪 C# 中的内存泄漏,而不是使用 C++。
猜你喜欢
  • 2011-11-14
  • 2018-01-14
  • 1970-01-01
  • 2011-03-07
  • 2019-01-25
  • 2013-08-10
  • 1970-01-01
  • 1970-01-01
  • 2019-10-01
相关资源
最近更新 更多