Я написал C ++ в течение 10 лет. Я столкнулся с проблемами с памятью, но они могли быть устранены с разумным усилием.
Последние пару лет я пишу на C #. Я все еще вижу много проблем с памятью. Их трудно диагностировать и исправить из-за недетерминированности, а также потому, что философия C # заключается в том, что вам не нужно беспокоиться о таких вещах, когда вы совершенно определенно это делаете.
Одна конкретная проблема, которую я нахожу, заключается в том, что я должен явно распоряжаться и очищать все в коде. Если я этого не сделаю, то профилировщики памяти на самом деле не помогают, потому что вокруг так много плывущей болтовни, что невозможно найти утечку во всех данных, которые они пытаются показать вам. Интересно, у меня неправильная идея, или инструмент, который у меня есть, не самый лучший.
Какие стратегии и инструменты полезны для устранения утечек памяти в .NET?
источник
Ответы:
Я использую Scitech MemProfiler, когда подозреваю утечку памяти.
До сих пор я обнаружил, что это очень надежный и мощный. Это спасло мой бекон хотя бы один раз.
GC очень хорошо работает в .NET IMO, но, как и на любом другом языке или платформе, если вы пишете плохой код, случаются плохие вещи.
источник
Просто для решения проблемы, связанной с забыванием, попробуйте решение, описанное в этом блоге . Вот суть:
источник
В нашем проекте мы использовали программное обеспечение Ants Profiler Pro от Red Gate. Это работает очень хорошо для всех приложений на основе языка .NET.
Мы обнаружили, что .NET Garbage Collector очень «безопасен» для очистки объектов в памяти (как и должно быть). Это будет держать объекты вокруг только потому, что мы могли бы использовать его когда-нибудь в будущем. Это означало, что нам нужно быть более осторожным с количеством объектов, которые мы надували в памяти. В конце мы преобразовали все наши объекты данных в «раздувание по требованию» (непосредственно перед тем, как запрашивается поле), чтобы уменьшить нагрузку на память и повысить производительность.
РЕДАКТИРОВАТЬ: Вот еще одно объяснение того, что я имею в виду под «надувать по требованию». В нашей объектной модели нашей базы данных мы используем Свойства родительского объекта, чтобы представить дочерний объект (ы). Например, если бы у нас была какая-то запись, которая ссылалась на какую-то другую запись «detail» или «lookup» на индивидуальной основе, мы бы структурировали ее так:
Мы обнаружили, что вышеуказанная система создала некоторые реальные проблемы с памятью и производительностью, когда в памяти было много записей. Поэтому мы переключились на систему, в которой объекты были раздуты только тогда, когда они были запрошены, а вызовы базы данных выполнялись только при необходимости:
Это оказалось намного более эффективным, потому что объекты оставались в памяти до тех пор, пока они не были необходимы (был вызван метод Get). Это обеспечило очень большое повышение производительности в ограничении обращений к базе данных и огромный выигрыш в объеме памяти.
источник
Вам все еще нужно беспокоиться о памяти, когда вы пишете управляемый код, если ваше приложение не тривиально. Я предлагаю две вещи: во-первых, читайте CLR через C #, потому что это поможет вам понять управление памятью в .NET. Во-вторых, научитесь использовать такой инструмент, как CLRProfiler (Microsoft). Это может дать вам представление о том, что вызывает утечку памяти (например, вы можете взглянуть на фрагментацию кучи больших объектов)
источник
Вы используете неуправляемый код? По словам Microsoft, если вы не используете неуправляемый код, утечки памяти в традиционном смысле невозможны.
Однако память, используемая приложением, не может быть освобождена, поэтому выделение памяти приложению может увеличиваться в течение срока службы приложения.
Для решения этой проблемы вы можете реализовать IDisposable . Если вы хотите ознакомиться с некоторыми стратегиями управления памятью, я бы предложил поискать IDisposable, XNA, управление памятью. поскольку разработчики игр должны иметь более предсказуемую сборку мусора и поэтому должны заставить GC делать свое дело.
Одна распространенная ошибка - не удалять обработчики событий, которые подписываются на объект. Подписка на обработчик событий предотвратит повторное использование объекта. Кроме того, взгляните на оператор using, который позволяет создать ограниченную область действия для ресурса ресурса.
источник
В этом блоге есть несколько действительно замечательных прохождений, использующих windbg и другие инструменты для отслеживания утечек памяти всех типов. Отличное чтение для развития ваших навыков.
источник
У меня просто была утечка памяти в службе Windows, которую я исправил.
Сначала я попробовал MemProfiler . Я нашел, что это действительно трудно использовать и совсем не удобно для пользователя.
Затем я использовал JustTrace, который проще в использовании и дает вам более подробную информацию об объектах, которые расположены неправильно.
Это позволило мне действительно легко решить проблему утечки памяти.
источник
Если наблюдаемые вами утечки связаны с неконтролируемой реализацией кэша, в этом сценарии вы можете рассмотреть возможность использования WeakReference. Это может помочь обеспечить освобождение памяти при необходимости.
Однако, ИМХО, было бы лучше рассмотреть сделанное на заказ решение - только вы действительно знаете, как долго вам нужно держать объекты вокруг, поэтому разработка подходящего служебного кода для вашей ситуации обычно является лучшим подходом.
источник
Я предпочитаю dotmemory от Jetbrains
источник
Большие пушки - Инструменты отладки для Windows
Это удивительная коллекция инструментов. С его помощью вы можете анализировать как управляемые, так и неуправляемые кучи и делать это в автономном режиме. Это было очень удобно для отладки одного из наших приложений ASP.NET, которые продолжали перерабатываться из-за чрезмерного использования памяти. Мне оставалось только создать полный дамп памяти живого процесса, работающего на рабочем сервере, весь анализ проводился в автономном режиме в WinDbg. (Оказалось, что какой-то разработчик злоупотреблял хранилищем памяти в памяти.)
В блоге «Если сломано это ...» есть очень полезные статьи на эту тему.
источник
Лучшее, что нужно иметь в виду, это отслеживать ссылки на ваши объекты. Очень легко получить висящие ссылки на объекты, которые вам больше не нужны. Если вы больше не собираетесь что-то использовать, избавьтесь от этого.
Привыкните к использованию провайдера кеша со скользящими истечениями, так что если что-то не ссылается на желаемое временное окно, оно разыменовывается и очищается Но если к нему обращаются много, он скажет в памяти.
источник
Один из лучших инструментов с помощью средств отладки для Windows , и принимая дамп памяти процесса с использованием ADPlus , а затем использовать WinDbg и Сос плагин для анализа памяти процесса, потоков и стек вызовов.
Вы также можете использовать этот метод для выявления проблем на серверах, после установки инструментов поделитесь общим каталогом, затем подключитесь к общему ресурсу с сервера (использование по сети) и выполните аварийный сбой или зависание дампа процесса.
Затем проанализируйте в автономном режиме.
источник
После одного из моих исправлений для управляемого приложения у меня было то же самое, например, как проверить, что у моего приложения не будет той же утечки памяти после моего следующего изменения, поэтому я написал что-то вроде инфраструктуры проверки выпуска объекта, пожалуйста, посмотрите пакет NuGet ObjectReleaseVerification . Вы можете найти образец здесь https://github.com/outcoldman/OutcoldSolutions-ObjectReleaseVerification-Sample и информацию об этом образце http://outcoldman.ru/en/blog/show/322
источник
В Visual Studio 2015 рассмотрите возможность использования готового инструмента диагностики использования памяти для сбора и анализа данных об использовании памяти.
Средство использования памяти позволяет сделать один или несколько снимков управляемой и собственной кучи памяти, чтобы понять влияние использования типов памяти на использование памяти.
источник
Один из лучших инструментов, которые я использовал, - DotMemory. Вы можете использовать этот инструмент как расширение в VS. После запуска приложения вы можете анализировать каждую часть памяти (по объектам, именам и т. д.), которую использует ваше приложение, и сделать некоторый снимок этого Сравните это с другими снимками. DotMemory
источник