Физическая память SQL Server увеличивается после выполнения команд - PullRequest
1 голос
/ 21 января 2010

Я запускаю серверное приложение на Windows Server 2008 с SQL Server 2008, теперь мой сценарий как заданный.

  1. Я реализовал пользовательский пул соединений (почему я это сделал, это еще одна длинная история). поэтому я не открываю и не закрываю соединение по каждому запросу.

  2. Серверное приложение выполняет более тысячи DBCommand в минуту, используя 10 подключений, доступных в пуле.

  3. после выполнения команды, и я не очищаю соединение (потому что я понятия не имею, что чистить и как чистить, не закрывая и не открывая его снова), а также я не уничтожаю сам объект Command.

  4. Когда серверное приложение выходит из строя, оно сбрасывает все соединения, вызывая для них метод close.

Теперь я заметил, что после теста 1 часа или 2 процесса sqlserver обходит память 3Gig, затем я закрыл серверное приложение, даже если занятая память не была освобождена или уменьшена (согласно диспетчеру задач и монитору ресурсов) после этого я перезапустил sqlserver, чтобы освободить память.

Теперь вот мой вопрос.

  1. Нужно ли мне каждый раз вызывать объект Dispose of DBCommand, если да, то будет ли это влиять на объект подключения.

  2. Указанная выше проблема вызывает то, что я заметил, или есть и другие причины.

  3. Есть ли способ очистить соединение, не закрывая его, и какой мусор нужно очищать после каждого выполнения DbCommand.

Спасибо Mubashar

Ответы [ 4 ]

2 голосов
/ 21 января 2010

Затем я закрыл серверное приложение, даже если занятая память не была освобождена или уменьшена (согласно диспетчеру задач и монитору ресурсов) [...]

Поскольку закрытие приложения удаляет все объекты, это наблюдение ясно показывает, что проблема потери памяти не связана с тем, что ваши объекты не удаляются. (Тем не менее, как правильно заметил Дэвид, всегда удаляйте IDisposables.)

Таким образом, вы должны посмотреть на конфигурацию памяти вашего SQL Server. Обратите внимание, что, если память доступна, SQL Server, использующий эту память, хорошо . Неиспользованная память - пустая трата денег. Обычно SQL Server освобождает память, когда какой-то другой процесс нуждается в этом:

Когда SQL Server использует память динамически, он периодически запрашивает систему, чтобы определить объем доступной физической памяти. SQL Server увеличивает или уменьшает буферный кэш, чтобы освободить физическую память в диапазоне от 4 до 10 МБ в зависимости от активности сервера. Это предотвращает подкачку Microsoft Windows NT® 4.0 или Windows® 2000. Если памяти недостаточно, SQL Server освобождает память для Windows NT 4.0 или Windows 2000, которая обычно попадает в список свободных. Если свободной памяти больше, SQL Server рекомендует память в буферный кеш. SQL Server добавляет память в буферный кеш, только когда его рабочая нагрузка требует больше памяти; сервер в состоянии покоя не увеличивает свой буферный кеш.

Итак, если ваш сервер не начнет чрезмерно менять местами, я бы не стал сильно беспокоиться о потреблении памяти SQL Server.

1 голос
/ 21 января 2010
  1. Always Dispose() IDispose -ables.

  2. Понятия не имею.

  3. Используйте sp_reset_connection для сброса соединения перед его возвратом в пул.

1 голос
/ 21 января 2010

SQL Server будет использовать много памяти и не будет возвращать ее до тех пор, пока это не будет необходимо, поэтому вы всегда должны запускать SQL на выделенной машине. Вы можете настроить максимальный предел памяти, если вам придется использовать его в общей среде, но приложение не сможет заставить SQL освободить память.

0 голосов
/ 21 января 2010

Пул соединений контролируется, и параметры передаются в строку соединения, которая в основном содержит следующее:

· Тайм-аут соединения

· Минимальный размер бассейна

· Максимальный размер пула

· Объединение

Если вы видите, что ваше приложение генерирует огромное количество соединений за очень короткий промежуток времени, то сначала вы проверяете свое приложение на наличие открытых соединений и обязательно закрываете их, как только заканчиваете работать с ними. Закрытое соединение не будет фактически закрыто и будет доступно для использования другим запросом к серверу. Специально проверьте ваши объекты DataReader и закройте их, как только они выйдут из контекста. Иногда разработчик использует несколько DataReader во вложенном цикле и закрывает все DataReader в пункте finally. Не делайте этого и попробуйте остановить DataReader, как только вы выйдете из цикла. Да, вы всегда можете снова проверить состояние объекта DataReader в предложении finally, а если не закрыто, вы можете закрыть его.

Теперь проверьте настройку ConnectTimeout до минимума, скажем, за 1 секунду. Это устанавливает срок жизни соединения в пуле, закрытом Приложением, и устанавливает для MaxPoolSize максимальное ограничение вашего сервера. Я думаю, это было бы 100, если бы ни одно другое приложение не было подключено к той же базе данных сервера. Установите значение MinPoolSize равным 5, так как вы установили бы ConnectTimeOut на минимум, и в этом случае, чтобы пул соединений работал эффективно, вам потребуется, чтобы некоторые соединения были всегда доступны.

Попробуйте эти настройки и изменения. Надеюсь, что это сработает к вашему удовлетворению.

Спасибо

Раджив Ранджан Лалл

...