У меня есть служба без сохранения состояния, которая использует клиентский API Fabric , чтобы выполнить итерацию по всем приложениям и службам в кластере и проверить их работоспособность.
Как только он получает все услуги (около 1000), он выполняет следующий код:
var tasksList = new List<Task>();
IEnumerbale<Application> applications = await GetClusterApplications();
foreach (var application in applications)
{
cancellationToken.ThrowIfCancellationRequested();
var servicesList = await GetApplicationServices(application);
var task = Task.Run(async () =>
{
foreach (var service in servicesList)
{
await _client.TestManager.ValidateServiceAsync(service, TimeSpan.FromSeconds(10), cancellationToken);
}
}, cancellationToken);
tasksList.Add(task);
}
Task.WaitAll(tasksList.ToArray());
этот код занимает ~ 4 минуты, а через 45 секунд мы начинаем еще одну итерацию.
Проверяя память, она увеличивается каждый раз, когда выполняется код. Я сравнил кучу до достижения кода выше, а затем.
Вот дамп кучи:
Почему существует так много объектов CancellationTokenSource? Что такое SparselyPopulatedArrays?
И самый большой вопрос: кто хранит ссылки на эти объекты, не позволяя GC собирать их?
Кстати, приведенный выше код обернут в метод, который вызывается каждый интервал времени, как объяснено.