Я пытаюсь проверить, как обрабатываются тяжелые объекты внутри .net BlockingCollection
.Сборщик мусора не в состоянии восстановить ресурсы памяти
Я получаю тяжелые объекты, используя какой-либо API, и хочу обрабатывать его в нескольких потоках. Для этого у меня есть один поток, который читает тяжелые объекты и нажимает их на несколько потоков, где каждый поток имеет свою собственную блокирующую коллекцию, и каждый из этих потоков выводит объект из коллекции и процесса. Я ожидаю, что когда объект будет удален из всей коллекции, где бы он ни сидел, GC должен уметь его очищать. Эта очистка не происходит, и моя программа выходит из памяти.
Вызов GC.Collect()
между ними помогает мне завершить процесс, но он имеет значительный удар по производительности, который я не могу себе позволить.
Вопрос только в том, почему сборщик мусора не может высвободить ресурсы здесь, даже если объекты выходят за рамки.
public class DummyProcessor
{
List<BlockingCollection<object>> listOfBlockingCollection = null;
void ProcessCollection(object blockingCollection)
{
BlockingCollection<object> collection = (BlockingCollection<object>)blockingCollection;
while (collection.IsCompleted == false)
{
object heavyObject = collection.Take();
CallExternalProcess(heavyObject);
}
}
private void CallExternalProcess(object heavyObject)
{
throw new NotImplementedException();
}
public void Analyze(object heavyObject)
{
if (listOfBlockingCollection == null)
{
listOfBlockingCollection = new List<BlockingCollection<object>>();
for (int i = 0; i < 25; i++)
{
BlockingCollection<object> coll = new BlockingCollection<object>();
listOfBlockingCollection.Add(coll);
Thread pt = new Thread(new ParameterizedThreadStart(ProcessCollection));
pt.Start(coll);
}
}
for (int i = 0; i < 25; i++)
{
listOfBlockingCollection[i].Add(heavyObject);
}
}
}
Вы сказали, что 'GC.Collect()' заставляет его работать, это означает, что сборщик мусора может собирать предметы, он просто не хочет этого делать. Вы пытались запустить профилировщик памяти в программе до такой степени, что она сбой с ошибкой из памяти? Возможно, объекты не выходят за рамки, когда вы думаете, что они есть, вы добавляете один и тот же объект во все 25 коллекций, если один из потоков работает медленно, все объекты, которые все еще нужно обрабатывать, не могут быть собраны. Мне все еще интересно, почему вы используете 25 коллекций, которые обрабатывают один и тот же объект 25 раз. –
@ScottChamberlain Профайлер памяти Visual Studio работает очень медленно, возможно, мне нужно будет запустить его на ночь. Но я уверен, что эти объекты не выпущены даже после того, как они удалены из всей коллекции. Код, который я представил, - это обзор того, что происходит в исходном коде. Тот же объект добавляется к нескольким коллекциям, потому что каждая коллекция обрабатывается по-своему и записывается в другой хранилище данных в их собственном формате. – Bikswan
Я был главным поклонником [dotMemory] (https://www.jetbrains.com/dotmemory/), он поставляется с Resharper, если он у вас есть, или у него также есть бесплатная 5-дневная пробная версия, если вы этого не сделаете. –