Я использую 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
{
}
}
Кроме того, очень высокое использование памяти не обязательно является утечкой памяти. Использование памяти оставаясь high, когда рассматриваемая память больше не нужна, является утечкой памяти, и вы ничего об этом не сказали.





Вот кое-что, что я узнал всего несколько недель назад от документация по методу 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)
{
...
}
}
Ух ты, не знал этого!
@DourHighArch Я правильно знаю ?! Я много лет занимался программированием AD на C#, даже не подозревая об этом. Я просто случайно наткнулся на это.
Пожалуйста, объясните, что заставило вас сделать вывод: «Моя программа быстро использует память с 0 до 2 ГБ». Вы смотрите на диспетчер задач? Это не показывает, сколько памяти использует ваша программа; вам нужно использовать профилировщик памяти.