【问题标题】:Memory leak when using time in NHibernate SQL query在 NHibernate SQL 查询中使用时间时的内存泄漏
【发布时间】:2009-03-09 13:44:22
【问题描述】:

我在我的 ASP.NET 应用程序中使用 NHibernate 来连接到 MS SQL Server 2005 数据库。在某些情况下,我需要编写自己的 SQL 查询。但是,我注意到每次执行以下代码时,SQL Server 线程都会泄漏大约 50 KB 的内存:

NHibernate.ISession session = NHibernateSessionManager.Instance.GetSession();

ISQLQuery query = session.CreateSQLQuery(
  "select {a.*} from t_alarm a where a.deactivationtime > '" +
  DateTime.UtcNow.ToString("yyyy-MM-dd HH:mm:ss") +
  "'");

query.AddEntity("a", typeof(TAlarm));
System.Collections.IList aList = query.List();

当我查看 Windows 任务管理器时,我看到进程 sqlservr.exe 每次运行此代码时都会增加 50 KB 的内存使用量。

这是真正有趣的部分。如果我在上面的代码中将"yyyy-MM-dd HH:mm:ss" 替换为"yyyy-MM-dd HH:mm"(即我删除秒数),内存泄漏就会停止。

更新:显然内存泄漏实际上并没有停止。他们只是每分钟显示一次。大概是当 SQL 查询发生变化时。

两种情况下返回的结果是一样的。

有人知道这里发生了什么吗?

【问题讨论】:

  • 您能否解释一下您是如何得出 SQL Server 泄漏的结论的?
  • 当我查看 Windows 任务管理器时,我看到进程 sqlservr.exe 每次运行此代码时都会增加 50 KB 的内存使用量。我也将其添加到问题中。

标签: sql-server sql-server-2005 nhibernate datetime memory-leaks


【解决方案1】:

一) 在示例中,您没有正确处理 NHibernate 的 Session,因此与 DB 的连接保持打开状态。

使用 using() {} statemenet 或 try{} cath{} finally{} 正确关闭连接。

B)你写不使用SQL参数,那么SQL Server将认为这是一个新的命令每次执行它时SQL命令 - 更确切地说每一秒(或者,如果你删除:ss的一部分,那么每分钟)。使用 SQL 参数(就像 NHibernate 在使用 HQL、Criteria 或 QBE 查询时所做的那样),它将被正确缓存,内存消耗更少。

希望这会有所帮助;)

【讨论】:

  • 我同意,我也许应该关闭会话。我会仔细看看的。但是,在这种情况下没有任何区别。但是我使用 HQL 重写了查询,从而解决了问题。非常感谢。
【解决方案2】:

您可能已将查询计划添加到过程缓存中?

sqlservr.exe 占用内存并且不会释放它,除非它在其他应用程序需要它时必须这样做。因此,数据库服务器是独立的,而不是多用途的。

From BOL: Dynamic Memory Management

在具有 2 GB RAM 的 32 位 PC 上,SQL Server 2000 将最大消耗 1.7 GB RAM。有一篇知识库文章对此进行了描述。

在这种情况下,通过提供秒数,您隐含地声明了“datetime”类型,而不是“smalldatetime”类型。这可能会影响您的查询计划。您可能对“a.deactivationtime”进行了隐式转换

【讨论】:

  • 感谢您提供内存使用信息。这让我感到更平静,也许这并不是我最初想的那么大的问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-12-24
  • 2021-07-06
  • 2013-10-11
  • 1970-01-01
相关资源
最近更新 更多