Как настроить визуал студио 13 чтобы она не тратила много памяти

Обновлено: 07.07.2024

BusinessObjectEditor 1.0
Information about my package

CodeRush for Visual Studio 16.1.5.0
CodeRush for Visual Studio

Command Bus, Event Stream and Async Manager Merq
Provides ICommandBus, IEventStream and IAsyncManager MEF services for loosely coupled Visual Studio extension components communication and integration.

CreateLayoutWizard 1.0
Create layout wizard.

DevExpress.DeploymentTool 1.0
A useful tool for deploying DevExpress assemblies.

DevExpress.ExpressApp.Design.DynamicPackage 1.0
DevExpress VSIX Package

DevExpress.ExpressApp.DesignPackage 1.0
DevExpress VSIX Package

DevExpress.Win.LayoutAssistant Extension 1.0
DevExpress.Win.LayoutAssistant Visual Studio Extension Detailed Info

DevExtreme.Design 16.1.5
DevExtreme Visual Studio integration package

GitHub.VisualStudio 2.2.0.11
A Visual Studio Extension that brings the GitHub Flow into Visual Studio.

MySQL for Visual Studio 1.2.6
Data design and management tools for MySQL. Copyright © 2007-2015 Oracle, Inc.

Python Tools for Visual Studio 2.2.50113.00
Python Tools for Visual Studio provides IntelliSense, projects, templates, Interactive windows, and other support for Python developers.

Python Tools for Visual Studio - Django Integration 2.2.50113.00
Provides templates and integration for the Django web framework.

Python Tools for Visual Studio - Profiling Support 2.2.50113.00
Profiling support for Python projects.

SQL Server Data Tools 14.0.60519.0
Microsoft SQL Server Data Tools

TypeScript 1.8.36.0
Средства TypeScript для Visual Studio

Workflow Manager Tools 1.0 1.0
Этот пакет содержит компоненты, необходимые для интеграции Visual Studio со службой Workflow Manager.

Xamarin 4.2.1.62 (680125b)
Visual Studio extension to enable development for Xamarin.iOS and Xamarin.Android.

Xamarin.Android 7.0.2.37 (ce955cc)
Visual Studio extension to enable development for Xamarin.Android.

Xamarin.iOS 10.2.1.5 (44931ae)
Visual Studio extension to enable development for Xamarin.iOS.

XtraReports package 1.0
XtraReports package

Визуализатор PreEmptive Analytics 1.2
Расширение Microsoft Visual Studio для визуализации агрегированных сводок, полученных от продуктов PreEmptive Analytics.

Инструменты Visual Studio для Apache Cordova Update 10
Инструменты Visual Studio для Apache Cordova

Инструменты мобильных услуг Microsoft Azure 1.4
Инструменты мобильных услуг Microsoft Azure

Инструменты разработчика Office для Visual Studio 2015 RUS 14.0.23930
Инструменты разработчика Microsoft Office для Visual Studio 2015 RUS

Общие инструменты Windows Azure 1.8
Предоставляет общие службы для использования мобильными службами и инструментами Microsoft Azure.

Пакет средств Application Insights для Visual Studio 7.18.00214.2
Средства Application Insights для Visual Studio

Система проектов JavaScript 2.0
Система проектов JavaScript

Языковая служба JavaScript 2.0
Языковая служба JavaScript

Проблема
1. Открываю файл.
Visual Studio потребляет:
- 60% - процессора;
- 1,4 Гб - оперативной памяти;
2. Провожу отладку.
Всё работает нормально
3. После отладки.
Visual Studio потребляет:
- 1% - процессора;
- 0,45 Гб - оперативной памяти;


Вопрос
1. Почему происходит большое потребление оперативной памяти?


После написания прошлой статьи, я понял, что у меня осталось еще некоторое количество информации, не относящейся к ускорению компиляции решения, но позволяющей несколько повысить производительность самой Visual Studio в процессе работы над кодом. А поскольку мы все-таки работаем над кодом изрядное количество времени, намного приятнее делать это в быстро работающей IDE. К сожалению, в этой статье не будет графиков, поскольку весьма тяжело измерить, насколько стало быстрее открываться меню или какое-то окно. Тем не менее, я надеюсь, что кто-то может найти для себя в этих советах что-то ценное и сэкономить себе немного времени.

Добавьте /nosplash к ярлыку запуска Visual Studio
Честно говоря, время запуска уменьшится не сильно, но психологически будет казаться, что Студия грузится быстрее.

Отключите кнопку F1
Это делается в «Environment->Keyboard». Вы ведь всё-равно не пользуетесь этой кнопкой, правда? А если случайно нажмёте, то, в зависимости от версии VS начнут открываться новые окна или запуститься браузер — всё это весьма долго.

Выключите анимацию
«Environment->General->Animate environment tools». Оставим анимацию фанатам красивостей. А мы ведь суровые программисты, нам ни к чему.

Отключите стартовую страницу
Она занимает время при запуске студии (в особенности, если лезет в Интернет за всякими новостями и советами). Отключается в «Environment->Startup».

Выключите «Track Active Item in Solution Explorer»
Неужели Вы правда ею пользуетесь? Если нет — выключите. Отключается в «Projects and Solutions»

Отключение разнообразных красивостей
Вот тут об этом написано детальнее. Отключается в «Environment->General->Visual experience»

Удаление лишних плагинов
Каждый плагин — это минус к производительности Студии. Если у Вас стоит что-то лишнее — удаляйте.

  • Закройте Visual Studio.
  • Удалите все .ncb файлы для Вашего решения.
  • Удалите или переименуйте файл C:\Program Files\Microsoft Visual Studio 9.0\VC\vcpackages\feacp.dll (часть «9.0» отличается для разных версий Visual Studio).

Запуск Студии и компиляция проекта перед приходом на работу
На моей рабочей машине каждое утро, за час до моего прихода на работу запускается скрипт, закрывающий Visual Studio, делающий update кода из репозитория и по-новому запускающий Студию и компиляцию решения в ней. Приходя на работу я вижу откытую IDE, в которой сразу видно текущее состояние решения (компилируется\нет) и лог процедуры update, по которой понятно что именно изменилось со вчерашнего вечера. Всё это экономит мне 10 минут ежедневно.

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

Чтобы проверить эту функцию, я создал еще один пример приложения. На этот раз он работает с файлами, и я попытался создать симуляцию процесса, занимающего много памяти.

Настройка

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

Как видно из кода, который я здесь показываю, я ссылаюсь на путь, указывающий на папку с именем Temporary . Чтобы проверить это, я скопировал туда набор маленьких и не очень маленьких файлов (кучу больших текстурных файлов и фильм). И это в значительной степени все, что нужно для симуляции интенсивного потребления памяти.

Испытывать это — получать и анализировать результаты

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

Сделав это, давайте посмотрим на результаты. Как и в предыдущих методах, есть график, показывающий загрузку процессора во время выполнения.

Там процессор довольно загружен для процесса, как я начал, и есть некоторые критические всплески. Но это не та метрика, которую я ищу.

Функции, выделяющие большую часть памяти

Первый индикатор, который нас интересует для этой сессии профилирования. Единственное, что в нем есть, это то, что он немного предвзят Метод ReadAllBytes, конечно, потребляет много памяти, но не 100%. Так почему же тогда процент такой высокий? Из-за того, что он должен был читать большой файл, он занимал столько памяти, что другие вызовы методов считались незначительными с точки зрения памяти. Чтобы продемонстрировать этот факт, я собираюсь удалить большой файл из папки и снова запустить процесс профилирования. Вот что я получил в конце концов:

Это выглядит более реалистично — хотя суммы действительно незначительны, они не равны нулю.

Если вы нажмете на один из методов, вы сможете просмотреть данные в более подробном представлении.

Прежде всего, вы можете непосредственно увидеть во фрагменте кода объем памяти, выделенный для конкретных вызовов. Самый дорогой звонок выделен красным. Теперь измените представление на Inclusive Allocations :

Теперь код выделен немного по-другому, кроме того, выделены две дополнительные строки:

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

Типы с наибольшим количеством выделенной памяти

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

Очевидно, что байтовый массив выделяет большую часть возможной памяти, используемой приложением, поскольку именно это я и использую для хранения содержимого файла. Но, как и в предыдущем индикаторе, данные здесь не соответствуют действительности. Другие типы данных выделяют определенные объемы памяти, и если я запускаю приложение, пропуская большой файл, вот что я получаю:

Хотя объем памяти очень маленький, он снова отличается от нуля. Иногда такое округление может быть неудобным (когда вам необходимо точно знать объем выделенной памяти), но в общих случаях это избавляет разработчика от просмотра значений, подобных 0,0001 (учитывая пропорции, заданные другими типами данных).

Тем не менее, даже учитывая, что показанные значения могут быть 0,00, разработчик все еще может просматривать фактические значения, независимо от того, насколько они малы. Для этого нажмите на перечисленный тип.

Отображаемая таблица подробно описывает количество исключительных и включающих выделений (и байтов) для каждого типа данных, даже для тех, которых не было в начальном списке. Для строки (в первоначальном списке указано как 0,00%) мы видим, что было 17802 включительно (не включая конец) байта.

ПРИМЕЧАНИЕ. Эти значения одинаковы, поскольку во время выборки из памяти значения обобщаются в общую сумму типа внутри одного метода — в моем случае это был Main, и у меня не было внешних вызовов или назначений.

Для сравнения в массиве байтов используется 780 715 158 байт. В этом случае процент для строки будет 0,0022% . Причина округления значения до нуля здесь ясна.

Типы с большинством экземпляров

Если предыдущий индикатор был основан на количестве байтов, то этот основан на количестве распределений. Давайте посмотрим, что записано для текущей сессии:

Этот индикатор является автономным и не изменяется, чтобы увидеть видимые изменения, если я изменю условия работы приложения. В качестве примера метода, который генерирует несколько строковых экземпляров, которые влияют на этот индикатор, я могу назвать Console.WriteLine .

Вывод

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

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

Выделение памяти в среде выполнения CLR является недорогой операцией, но ее освобождение может сопровождаться значительными накладными расходами. По этой причине группы небольших методов, выделяющих большие объемы памяти, могут отнимать совсем немного процессорного времени и быть практически незаметны в отчете профилировщика времени, но при этом вызывать значительные задержки на сборку мусора в случайных точках выполнения приложения. В своей практике мы встречали приложения, где память выделялась без должного внимания, и нам удавалось увеличивать их производительность - иногда в 10 раз - оптимизировав выделение памяти и управление ею.

Для профилирования выделения памяти мы будем использовать два профилировщика - вездесущий профилировщик Visual Studio, поддерживающий режим профилирования выделения памяти, и профилировщик CLR Profiler - самостоятельный и бесплатный инструмент. К сожалению, оба инструмента часто оказывают значительное влияние на производительность приложений, интенсивно использующих динамическую память, потому что для каждой операции выделения памяти профилировщик выполняет последовательность действий по сохранению информации для последующего составления отчетов. Тем не менее, результаты могут оказаться настолько ценными, что даже 100-кратное замедление при профилировании можно потерпеть.

Профилировщик выделения памяти Visual Studio

Профилировщик Visual Studio способен собирать информацию об операциях выделения памяти и жизненном цикле объектов (которые освобождаются сборщиком мусора) в обоих режимах, дискретном и инструментированном. В дискретном режиме профилировщик собирает информацию о выделении памяти в приложении в целом. В инструментированном режиме информация собирается только из инструментированных модулей.

Представление Summary (Сводка) с результатами профилирования выделения памяти

В представлении Functions для каждого метода будет указано количество объектов и количество байтов памяти, выделенных методом (как обычно, включительные и исключительные значения). В представлении Function Details (Сведения о функции) будет представлена информация о вызывающих и вызываемых функциях, а также указаны строки кода с объемами выделенной ими памяти в поле слева:

Представление Function Details

Но самая интересная информация содержится в представлении Allocation (Выделение), показывающем, какие ветви в стеке вызовов выделили памяти больше всего:

Представление Allocation

Позже мы узнаем, насколько важно отказаться от использования временных объектов, и обсудим феномен «кризиса среднего возраста» объектов, оказывающего существенное влияние на производительность, который проявляется в способности объектов переживать несколько циклов сборки мусора. Идентифицировать наличие этого явления в приложении можно с помощью представления Object Lifetime (Жизненный цикл объектов), сообщающем, в каком поколении объекты были утилизированы. Это представление поможет увидеть, имеются ли объекты, пережившие слишком много циклов сборки мусора. На рисунке ниже можно видеть, что все объекты строк, созданные приложением (и занимающие более 1 Гбайта памяти!) были утилизированы в нулевом поколении, а это означает, что ни одному из них не удалось прожить дольше одного цикла сборки мусора:

Представление Object Lifetime (Жизненный цикл объектов)

Хотя отчеты о выделении памяти, генерируемые профилировщиком Visual Studio, отличаются богатством информации, в них все же имеются некоторые недостатки. Например, трассировка стека вызовов с целью сгруппировать операции выделения памяти по типам объектов занимает достаточно много времени, если выделение памяти производится во множестве разных мест (что всегда верно для строк и массивов байтов). Профилировщик CLR Profiler поддерживает несколько дополнительных особенностей, делающих его ценной альтернативой профилировщику Visual Studio.

CLR Profiler

Профилировщик CLR Profiler - это отдельный инструмент профилирования, не требующий установки и занимающий менее 1 Мбайта дискового пространства. Как дополнительное преимущество, он распространяется с исходными текстами, которые наверняка заинтересуют тех, кто пожелает заняться созданием собственных инструментов, использующих CLR Profiling API. Он способен подключаться к выполняющимся процессам (если используется версия CLR не ниже 4.0) или запускать выполняемые файлы, и регистрировать все операции выделения памяти и события сборки мусора.

Пользоваться профилировщиком CLR Profiler очень просто - запустите профилировщик, щелкните на кнопке Start Application (Запустить приложение), выберите приложение для профилирования и дождитесь появления отчета - богатство информации для кого-то может оказаться ошеломляющим. Мы рассмотрим здесь некоторые отчеты профилировщика, а полное руководство вы найдете в документе CLRProfiler.doc, входящем в состав загружаемого пакета. Как обычно, для экспериментов с профилировщиком вы можете использовать пример приложения JackCompiler.exe или свое приложение.

На рисунке ниже показан главный отчет, появляющийся после завершения профилируемого приложения. Он содержит основные сведения, касающиеся выделения памяти и сборки мусора. Далее из этого отчета можно пойти в нескольких направлениях. Мы сконцентрируемся на исследовании источников выделения памяти, чтобы понять, в каком месте приложения создается больше всего объектов (этот отчет напоминает представление Allocation профилировщика Visual Studio). Мы могли бы заняться исследованием сборки мусора, чтобы узнать, какие объекты утилизируются. Наконец, можно было бы исследовать содержимое динамической памяти, чтобы получить представление о ее распределении.

Главный отчет профилировщика CLR Profiler, отображающий информацию о выделении памяти и сборке мусора

Щелчок на кнопке Histogram (Гистограмма) рядом с полем Allocated bytes (Выделено байтов) или Final heap bytes (Конечный объем кучи в байтах) выведет гистограмму по типам объектов, сгруппированных по размерам. Эта гистограммы можно использовать для выявления больших и малых объектов, а также объектов, создаваемых чаще других. На рисунке ниже показана гистограмма для всех объектов, создаваемых нашим примером приложения:

Все объекты, созданные профилируемым приложением

Каждый столбик представляет объекты определенного размера. Легенда справа содержит общее число созданных экземпляров каждого типа и объем выделенной памяти в байтах.

Щелчок на кнопке Allocation Graph (График выделения) откроет отчет о выделении памяти в дереве стека вызовов для всех объектов в приложении. Информация в этом отчете сгруппирована так, чтобы легко можно было перейти от методов, выделивших больше всего памяти, к отдельным типам объектов и посмотреть, какие методы создали больше всего экземпляров этих типов. На рисунке ниже показана малая часть графика выделения памяти, начиная от метода Parser.ParseStatement(), выделившего (включительно) 372 Мбайт памяти и до различных методов, вызываемых им. (Кроме того, в остальных отчетах профилировщика CLR Profiler присутствует пункт контекстного меню Show who's allocated (Показать, для кого выделена память), открывающий отчет с графиком выделения памяти для подмножества объектов приложения.)

График выделения памяти в профилируемом приложении

Здесь показаны только методы, информация о фактических типах объектов находится на графике правее.

Щелчок на кнопке Objects by Address (Объекты по адресу) отобразит области управляемой динамической памяти в виде слоев; чем ниже слой, тем он старше. Подобно археологу вы можете погружаться в более глубокие слои и выяснять, какие объекты занимают память в вашем приложении. Этот отчет можно также использовать для диагностики фрагментации динамической памяти:

Визуальное представление динамической памяти приложения

Метки слева - это адреса, метки «gen 0» и «gen 1» - это подразделы динамической памяти.

Наконец, щелчок на кнопке Time Line (График времени) в разделе Garbage Collection Statistics (Статистика сборки мусора) откроет отчет с информацией об отдельных циклах сборки мусора и их влиянии на динамическую память приложения:

График сборки мусора во времени

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

Этот график можно использовать для определения типов утилизируемых объектов, и получения представления о том, как изменяется распределение динамической памяти после сборки мусора. С его помощью можно также выявлять утечки памяти, когда сборщик мусора освобождает недостаточно памяти, из-за того, что приложение продолжает удерживать все увеличивающееся количество объектов.

Графики и гистограммы выделения памяти - весьма полезные инструменты анализа, но иногда важнее бывает выявить ссылки между объектами, а не объемы выделяемой памяти в разных методах. Например, когда в приложении обнаруживаются утечки управляемой памяти, очень полезно пройтись по динамической памяти, чтобы найти категории объектов, занимающие наибольшие объемы памяти и узнать, какие объекты на них ссылаются, мешая сборщику мусора утилизировать их. Пока профилируемое приложение выполняется, щелкните на кнопке Show Heap now (Показать кучу сейчас), чтобы сгенерировать дамп динамической памяти для последующего исследования с целью классификации ссылок между объектами.

На рисунке ниже показан отчет профилировщика сразу с тремя дампами динамической памяти, расположенными друг над другом, показывающий увеличение количества объектов типа byte[], удерживаемых очередью объектов, готовых к завершению (freachable queue), из-за наличия ссылок на них в объектах Employee и Schedule:

Три дампа динамической памяти друг над другом, показывающих, что в куче удерживаются 11 Мбайт экземпляров типа byte[]

Ha рисунке ниже показаны результаты выбора пункта Show New Objects (Показать новые объекты) контекстного меню, чтобы оставить в отчете только объекты, созданные в период времени между сохранением второго и третьего дампов:

Новые объекты, созданные между в период между сохранением последнего и предпоследнего дампов

На этом графике видно, что источником утечки памяти является цепочка ссылок из очереди объектов, готовых к завершению.

Дампы динамической памяти, созданные профилировщиком CLR Profiler, можно использовать для диагностики утечек памяти в приложениях, но средств визуализации, упрощающих это, в данном профилировщике явно недостаточно. Коммерческие инструменты, которые мы рассмотрим далее, предлагают более богатые возможности, включая автоматические средства обнаружения наиболее типичных источников утечек памяти, разнообразные фильтры и возможности более сложной группировки информации. Поскольку большинство из этих инструментов не сохраняют информацию о каждом объекте, размещенном в динамической памяти, и не сохраняют информацию о выделении памяти в разных методах, они имеют более низкие накладные расходы, что само по себе является большим преимуществом.

Коммерческие профилировщики памяти

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

Профилировщик памяти ANTS

Профилировщик ANTS Memory Profiler компании RedGate специализируется на анализе срезов динамической памяти. Ниже подробно описывается процесс использования ANTS Memory Profiler для диагностики утечек памяти. Если у вас есть желание самим повторить описываемые действия, загрузите пробную 14-дневную версию ANTS Memory Profiler, которую можно найти по адресу: ANTS Memory Profiler, и используйте ее для профилирования собственного приложения. Описание и скриншоты, представленные ниже, относятся к версии ANTS Memory Profiler 7.3, которая была последней на момент написания данных строк.

Следуя за экспериментом, описываемым ниже, вы можете использовать пример приложения FileExplorer.exe из папки с исходниками. Это приложение имитирует утечку памяти, выполняя обход дерева каталогов и не освобождая объекты с информацией о непустых каталогах.

Запустите приложение из профилировщика. (Подобно профилировщику CLR Profiler, ANTS поддерживает возможность подключения к выполняющимся процессам, начиная с версии CLR 4.0.)

По завершении инициализации приложения щелкните на кнопке Take Memory Snapshot (Сделать снимок памяти). Этот снимок будет служить основой для последующих исследований.

Накопив утечки памяти, сделайте еще один снимок динамической памяти.

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

Выберите определенный тип и щелкните на кнопке Instance Categorizer (Классификатор экземпляров), чтобы понять, какие ссылки удерживают в памяти объекты подозреваемого в утечках типа. (На этом этапе исследуются ссылки между типами - экземпляры типа A, ссылающиеся на экземпляры типа B, будут сгруппированы по типу.)

Исследуйте отдельные экземпляры подозреваемых в утечках типов, щелкнув на кнопке Instance List (Список экземпляров). Выберите несколько наиболее представительных экземпляров и щелкните на кнопке Instance Retention Graph (График зависимостей экземпляров), чтобы посмотреть, почему они удерживаются в памяти. (На этом этапе исследуются ссылки между отдельными объектами, и здесь можно выяснить причину, мешающую сборщику мусора утилизировать конкретные объекты.)

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

К концу процесса анализа у вас должно сложиться четкое представление, почему самые тяжеловесные объекты в вашем приложении не утилизируются сборщиком мусора. Существует множество причин, вызывающих утечки памяти, и их выявление проблемных объектов из миллионов имеющихся - это целое искусство.

На рисунке ниже показан пример сравнения двух снимков динамической памяти. Основные утечки памяти (в байтах) связаны с объектами string.

Сравнение двух снимков динамической памяти ANTS Memory Profiler

Детальный осмотр типа string после щелчка на кнопке Instance Categorizer (Классификатор экземпляров) наводит на мысль, что некоторое событие создает экземпляры FileInformation в памяти, которые в свою очередь хранят ссылки па объекты byte[]:

Описание удерживаемого в памяти объекта ANTS Memory Profiler

Как видно из рисунка, строки удерживаются в памяти массивами строк, которые сами удерживаются экземплярами типа FileInformation, которые в свою очередь удерживаются событием (через делегаты System.EventHandler).

Более детальное исследование конкретных экземпляров в представлении, выводимом после щелчка на кнопке Instance Retention Graph (График зависимостей экземпляров) в результате указывает, что источником утечек является статическое событие FileInformation.FileInformationNeedsRefresh:

График зависимостей экземпляров

Начальный анализ двух снимков динамической памяти SciTech .NET Memory Profiler

В пятом столбце списка указано число хранящихся в памяти экземпляров, а в седьмом - количество байтов, занимаемых ими. Основной объем памяти занимают объекты string, информация о которых скрыта здесь за всплывающей подсказкой.

Читайте также: