Я попал в проблему, когда мое приложение ASP.NET 4 MVC 2 + WCF использует большое количество памяти в приложении Windows 2008 64-bit во время нагрузочного тестирования, где оно будет использоваться почти через всю доступную память (8 ГБ) через несколько минут (у нас было мало рабочих процессов).
После профилирования с использованием ANTI Memory Profiler он показывал несколько интересных результатов:
- Увеличение управляемой памяти .NET с 15 Мбайт до 40 МБ. Однако это объясняется механизмом кэширования, который мы выполняли в программе. Однако сама .NET выделяет выделение почти 180 МБ свободного пространства, что неожиданно.
- Размер неуправляемой памяти значительно увеличивается до 120 МБ после того, как тестовый тест запускается примерно на 3 минуты (хотя наше приложение явно не использует какой-либо объект P/Invoke или COM. Однако мы использовали несколько COM + -объектов, которые после использования в блоке finally).
- Память становится фрагментированной.
- Оба элемента № 1 и 2 выше приводят к тому, что все приложение использует около 350 МБ сразу после теста нагрузки, работающего несколько минут, но если мы не остановим тест, он будет продолжать расти дальше.
Основываясь на элементе № 1 выше, я протестировал некоторое приложение для проверки того, связана ли проблема с нашим приложением или WCF. Приложение-тест просто загружает данные XML (около 300 КБ) в набор данных в многопоточном приложении. Когда логика хранится в программе EXE, приложение использует только 200 КБ (дополнительно 120 КБ с 40 КБ для неиспользуемой памяти) управляемую память из 24 МБ частных байтов после окончания (что приемлемо); , но когда логика размещается в WCF, приложение использует 66 МБ управляемой памяти (дополнительно 61 МБ от начала до 64 МБ свободной/неиспользуемой управляемой памяти). Таким образом, кажется, что WCF/ASP.NET - это тот, который сильно увеличивает память).
- Почему .NET выделяет столько свободного места в куче?. Понятно, что свободное пространство может быть некоторым Gen 0/Gen 1/Gen 2, которое GC-ed во время моментального снимка памяти, но я не думайте, что приложение действительно использует столько памяти.
- - нормальное поведение для WCF? Если да, любой способ изменить поведение, чтобы он использовал меньшую память?
- Как найти неуправляемую утечку памяти, особенно, что я не использовал неуправляемый код явно?
Цените свой совет по вышеуказанному вопросу.
Спасибо заранее,
Вилли