Утечка памяти в цикле DirectorySearcher - PullRequest
0 голосов
/ 02 мая 2018

Я использую 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
                        {

                        }
            }  

1 Ответ

0 голосов
/ 02 мая 2018

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

Из-за ограничений реализации класс SearchResultCollection не может освободить все свои неуправляемые ресурсы, когда это мусор собраны. Чтобы предотвратить утечку памяти, вы должны вызвать метод Dispose когда объект SearchResultCollection больше не нужен.

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

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