Исключение нехватки памяти веб-службы при заполнении ADO.Net DataSet - PullRequest
1 голос
/ 20 мая 2009

1) ClientApp выполняет асинхронный вызов ASP.Net 2.0 WebService 2) Веб-служба вызывает хранимую процедуру SQL Server 2005 3) Хранимая процедура возвращает вывод данных, таблица 150 МБ

Исключение из нехватки памяти выдается DataAdapter.Fill (...) при попытке выделить больше памяти для новых строк.

В пуле приложений IIS нет ограничений по максимальной памяти.

Есть ли максимальные ограничения использования памяти, установленные где-то еще на уровне IIS? Занимает ли таблица в 150 МБ больше места при чтении в память как DataSet? Существует ли сценарий (возможно, с WCF), когда результат процедуры никогда не должен находиться в памяти веб-сервера, а передавался бы напрямую клиенту?

Я бы предпочел не разбивать запрос на меньшие наборы данных, потому что клиент запрашивает их асинхронно. Сбор всех частей должен происходить также асинхронно, и каждый клиент должен будет реализовать асинхронный сбор для каждого вызова.

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

Ответы [ 2 ]

5 голосов
/ 21 мая 2009

Да, использование DataSets использует намного больше памяти, чем фактические данные. Сколько трудно определить количественно, но этот вопрос о StackOverflow предлагает более чем в 4 раза превышать исходный размер данных. Давайте предположим, что это правильно. 150 МБ данных раз 4 = 600 МБ памяти. Когда приложение ASP.NET использует около 800 МБ ОЗУ, оно начинает выдавать исключения OutOfMemoryException. Я не уверен, как этот предел совпадает с пределом памяти пула приложений. Вы пробовали / 3GB переключатель в boot.ini? (См. эту статью для получения инструкций)

Также обратите внимание, что если вы сериализуете свой DataSet, сериализатор может выделять огромные буферы для сериализации (до 10 раз больше исходного размера, см. эту статью . Вы указываете, что проблема возникает при чтении данные, так что это, вероятно, не является причиной вашей ошибки (но это может быть, если вы решите ошибку нехватки памяти и попытаетесь отправить данные по проводам).

Мой опыт работы с DataSets вначале может показаться хорошей идеей, но вы очень скоро столкнетесь с проблемами.

Другим (возможно, лучшим) решением было бы использование DataReader и чтение по одной строке за раз. Верните пакеты строк (т. Е. Используйте какую-то подкачку для данных) и поэкспериментируйте с размером каждой партии, чтобы найти точку соприкосновения между производительностью и использованием памяти. Потоковая передача WCF может помочь, но вам необходимо правильно настроить WCF, чтобы он мог возвращать такие огромные объемы данных за один вызов.

0 голосов
/ 20 мая 2009

Лучшие практики: а) не возвращать столько данных и б) использовать WCF вместо четырехлетней технологии (веб-сервисы ASMX).

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...