在NHibernate SQL查询中使用时间时内存泄漏

时间:2009-03-09 13:44:23

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

我在ASP.NET应用程序中使用NHibernate连接到MS SQL Server 2005数据库。在某些情况下,我需要编写自己的SQL查询。但是,我注意到每次执行以下代码时SQL服务器线程都会泄漏大约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查询发生变化时。

两种情况下返回的结果都相同。

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

2 个答案:

答案 0 :(得分:2)

您是否已在程序缓存中添加了查询计划?

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

From BOL: Dynamic Memory Management

在具有2 GB RAM的32位PC上,SQL Server 2000将最多消耗1.7GB RAM。有一篇KB文章描述了这一点。

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

答案 1 :(得分:2)

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

使用(){} statemenet或尝试{} cath {} finally {}来正确关闭连接。

b)您编写的SQL命令不使用SQL参数,因此每次执行时,SQL服务器都会将其视为一个新命令 - 更准确地说是每秒(或者如果删除:ss部分,则每分钟删除)。使用SQL参数(如使用HQL,Criteria或QBE查询时的NHibernate),它将以较少的内存消耗正确缓存。

希望这会有所帮助;)