Использование свободной памяти .NET (как предотвратить перераспределение / освобождение памяти ОС)

В настоящее время я работаю над веб-сайтом, который широко использует кэшированные данные, чтобы избежать двусторонних обращений.При запуске получаем "большой" граф (сотни тысяч разного вида объектов). Эти объекты извлекаются через WCF и десериализуются (мы используем буферы протокола для сериализации). Я использую профилировщик памяти redgate для отладки проблем с памятью (память, похоже, не соответствовала тому, сколько памяти нам нужно «после того», как мы закончили инициализацию и получили этот отчет

Global Report

Теперь, что мы можем собрать из этот отчет таков:

1) Большая часть памяти, выделенной .NET, свободна (возможно, она была правильно выделена во время десериализации, но теперь, когда она свободна, я хотел бы, чтобы она вернулась в ОС)

2) Память фрагментирована (что плохо, так как каждый раз, когда я обновляю кэш, мне нужно повторить процесс десериализации памяти, а это, в свою очередь, создает большой объект, который может вызвать исключение OutOfMemoryException из-за фрагментации)

3) У меня нет подскажите, почему пространство фрагментировано, потому что, когда я смотрю на кучу больших объектов, есть только 30 экземпляров, 15 объектов [] напрямую связаны с GC и совершенно не связаны со мной, 1 - это массив символов, также прикрепленный непосредственно к GC Куча, остальные 15 мои, но не являются причиной этого, так как я получаю тот же отчет, если я укажите их в коде.

Итак, мой вопрос: что я могу сделать, чтобы продвинуться дальше? Я не совсем уверен, что искать в отладке/инструментах, поскольку кажется, что моя память фрагментирована, но не мной, и .net выделяет огромное количество свободного места, которое я не могу освободить.

Также, пожалуйста, убедитесь, что вы правильно поняли вопрос, прежде чем отвечать, я не ищу способ освободить память в .net (GC.Собери), но освободить память, которая уже свободна в .net, в систему, а также провести дефрагментацию указанной памяти.

Обратите внимание, что медленное решение подходит, если есть возможность вручную дефрагментировать большую кучу, я был бы полностью за это, поскольку я могу вызвать его в конце RefreshCache, и это нормально, если для запуска требуется 1 или 2 секунды.

Спасибо за помощь!

Несколько заметок, которые я забыл: 1) Проект представляет собой веб-сайт .net 2.0, я получаю те же результаты, запуская его в пуле .net 4, а также, если я запускаю его в пуле .net 4, конвертирую в .net 4 и перекомпилирую.

2) Это результаты релизной сборки, поэтому отладочная сборка не может быть проблемой.

3) И это, вероятно, очень важно, я вообще не получаю этих проблем на сервере веб-разработчика, только в IIS, в веб-устройстве я получаю потребление памяти, довольно близкое к моему фактическому потреблению (хорошо больше, но не 5- В 10 раз больше!)

17
задан Ronan Thibaudau 21 March 2012 в 12:53
поделиться