Физическая память SQL Server увеличивается после выполнения команд

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

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

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

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

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

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

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

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

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

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

Спасибо Мубашар

4 ответа

Решение

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

Поскольку закрытие приложения удаляет все объекты, это наблюдение ясно показывает, что проблема потери памяти не связана с тем, что ваши объекты не удаляются. (Тем не менее, как правильно заметил Дэвид, всегда удаляйте 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. Всегда Dispose()IDispose-ables.

  2. Без понятия.

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

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

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

· Время ожидания подключения

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

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

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

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

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

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

Спасибо,

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

Другие вопросы по тегам