Утечка памяти в цикле DirectorySearcher

Я использую DirectorySearcher в операторе using для просмотра около 5000 объектов. При устранении неполадок выясняется, что свойство PropertiesToLoad вызывает массовую утечку памяти. Моя программа быстро использует от 0 до 2 ГБ памяти, если я устанавливаю свойство propertiesToLoad для каждого объекта. Таким образом поиск выполняется очень быстро, но имеет утечку памяти.

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

ПРИМЕЧАНИЕ. Мое приложение является многопоточным, поэтому поиск в AD выполняется одновременно в 10 потоках.

using (DirectorySearcher mySearcher = new DirectorySearcher(new DirectoryEntry("LDAP://rootDSE", null, null, AuthenticationTypes.FastBind)))
            { 
                        try
                        {
                            mySearcher.Filter = ("(&(objectClass=user)(sAMAccountName = " + object + "))");
                            mySearcher.SearchScope = SearchScope.Subtree;
                            mySearcher.CacheResults = false;
                            mySearcher.PropertiesToLoad.AddRange(new string[] { "canonicalName", "displayName", "userAccountControl" });

                            foreach (SearchResult result in mySearcher.FindAll())
                            {
                                try
                                {
                                    shareInfo.displayname = result.Properties["displayName"][0].ToString();
                                }
                                catch
                                {
                                    shareInfo.displayname = "N/A";
                                }

                                shareInfo.canName = result.Properties["canonicalName"][0].ToString();

                                int userAccountControl = Convert.ToInt32(result.Properties["userAccountControl"][0]);
                                bool disabled = ((userAccountControl & 2) > 0);
                                if (disabled == true)
                                    shareInfo.acctstatus = "Disabled";
                                else
                                    shareInfo.acctstatus = "Enabled";
                            }
                        }
                        catch
                        {

                        }
            }  

Пожалуйста, объясните, что заставило вас сделать вывод: «Моя программа быстро использует память с 0 до 2 ГБ». Вы смотрите на диспетчер задач? Это не показывает, сколько памяти использует ваша программа; вам нужно использовать профилировщик памяти.

Dour High Arch 02.05.2018 21:03

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

zzxyz 02.05.2018 21:09
Стоит ли изучать PHP в 2026-2027 годах?
Стоит ли изучать PHP в 2026-2027 годах?
Привет всем, сегодня я хочу высказать свои соображения по поводу вопроса, который я уже много раз получал в своем сообществе: "Стоит ли изучать PHP в...
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
Поведение ключевого слова "this" в стрелочной функции в сравнении с нормальной функцией
В JavaScript одним из самых запутанных понятий является поведение ключевого слова "this" в стрелочной и обычной функциях.
Приемы CSS-макетирования - floats и Flexbox
Приемы CSS-макетирования - floats и Flexbox
Здравствуйте, друзья-студенты! Готовы совершенствовать свои навыки веб-дизайна? Сегодня в нашем путешествии мы рассмотрим приемы CSS-верстки - в...
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Концепция локализации и ее применение в приложениях React ⚡️
Концепция локализации и ее применение в приложениях React ⚡️
Локализация - это процесс адаптации приложения к различным языкам и культурным требованиям. Это позволяет пользователям получить опыт, соответствующий...
Пользовательский скаляр GraphQL
Пользовательский скаляр GraphQL
Листовые узлы системы типов GraphQL называются скалярами. Достигнув скалярного типа, невозможно спуститься дальше по иерархии типов. Скалярный тип...
0
2
231
1

Ответы 1

Вот кое-что, что я узнал всего несколько недель назад от документация по методу FindAll:

Due to implementation restrictions, the SearchResultCollection class cannot release all of its unmanaged resources when it is garbage collected. To prevent a memory leak, you must call the Dispose method when the SearchResultCollection object is no longer needed.

Вы используете using в DirectorySearcher, но не в коллекции результатов. Попробуйте присвоить полученную коллекцию переменной, которую можно будет удалить позже:

using (var results = mySearcher.FindAll())
{
    foreach (SearchResult result in results)
    {
        ...
    }
}

Ух ты, не знал этого!

Dour High Arch 02.05.2018 22:40

@DourHighArch Я правильно знаю ?! Я много лет занимался программированием AD на C#, даже не подозревая об этом. Я просто случайно наткнулся на это.

Gabriel Luci 03.05.2018 14:08

Другие вопросы по теме