Утечка памяти при использовании времени в запросе NHibernate SQL - PullRequest
1 голос
/ 09 марта 2009

Я использую NHibernate в своем приложении ASP.NET для подключения к базе данных MS SQL Server 2005. В некоторых случаях мне нужно написать свои собственные запросы SQL. Однако я заметил, что поток SQL-сервера теряет около 50 КБ памяти каждый раз, когда я выполняю следующий фрагмент кода:

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 КБ при каждом запуске этого кода.

Вот действительно интересная часть. Если я в приведенном выше коде заменим "yyyy-MM-dd HH:mm:ss" на "yyyy-MM-dd HH:mm" (т.е. я уберу секунды), утечки памяти прекратятся.

Обновление: очевидно, утечки памяти на самом деле не прекращаются. Они просто показывают один раз в минуту вместо этого. Предположительно при изменении SQL-запроса.

Возвращенные результаты одинаковы в обоих случаях.

Кто-нибудь знает, что здесь происходит?

Ответы [ 2 ]

2 голосов
/ 10 марта 2009

а) В этом примере вы неправильно удаляете сессию NHibernate, поэтому соединение с БД остается открытым.

Используйте использование () {} statemenet или попробуйте {} cath {} finally {}, чтобы правильно закрыть соединение.

b) Написанная вами команда SQL не использует параметры SQL, поэтому сервер SQL будет видеть ее как новую команду каждый раз, когда вы ее выполняете, точнее каждую секунду (или если вы удалите: ss part, то каждую минуту). Используйте параметры SQL (как это делают NHibernate при использовании запросов HQL, Criteria или QBE), и они будут кэшироваться должным образом с меньшим потреблением памяти.

Надеюсь, это поможет;)

2 голосов
/ 09 марта 2009

Вы добавили план запроса в кеш процедур, возможно?

sqlservr.exe занимает память и не освобождает ее, если это не требуется, когда это требуется другим приложениям. Следовательно, серверы БД автономны и не являются многоцелевыми.

Из BOL: динамическое управление памятью

На 32-разрядном ПК с 2 ГБ ОЗУ SQL Server 2000 будет максимально использовать 1,7 ГБ ОЗУ. Есть статья в КБ, описывающая это.

В этом случае, предоставляя секунды, вы неявно указываете тип «datetime», а не тип «smalldatetime». Это может повлиять на ваш план запроса. Вы можете иметь неявное преобразование в "a.deactivationtime"

...