Подтвердить что ты не робот

.NET Framework - Возможные классы, не требующие памяти?

На днях я исследовал утечку памяти, которая запускала приложение с ~ 50 МБ до ~ 130 МБ в течение двух минут. Оказывается, проблема была в классе ConcurrentQueue. Внутри класса хранится связанный список массивов. Когда элемент выгружается из ConcurrentQueue, индекс в массиве сталкивается, но элемент остается в массиве (т.е. Он не установлен в null). Весь массив node отбрасывается после достаточного количества очередей /dequeues, поэтому это не технически является утечкой, но если положить большие объекты в ConcurrentQueue, это может быстро выйти из-под контроля. В документации не упоминается об этой опасности.

Мне было интересно, какие другие потенциальные ловушки памяти находятся в библиотеке базового класса? Я знаю о Подстроке один (то есть, если вы вызываете подстроку и просто держитесь за результат, вся строка будет по-прежнему в памяти). Любые другие, с которыми вы столкнулись?

4b9b3361

Ответ 1

Вы правы. Ошибка находится в методе System.Collections.Concurrent.ConcurrentQueue<T>+Segment.TryRemove(out T, ref ConcurrentQueue<T>.Segment).

Если вы посмотрите на этот метод в Reflector, вы увидите следующую строку:

result = this.m_array[low];

После него должна быть следующая строка:

this.m_array[low] = default(T);

Для справки вы можете увидеть, как это правильно реализовано в методе System.Collections.Generic.Queue<T>.Dequeue().

Ответ 2

Хотя это не прямая утечка памяти или специфическая для .net/BCL, существует конкатенация строк (с использованием проблемы + =). Это довольно интенсивный процессор в циклах из-за большого сбора мусора.

Ответ 3

В ConcurrentQueue будет сохранено максимум 31 объект, выделенный из очереди. Это не должно представлять огромную проблему, если вы не имеете дело с действительно большими объектными графами.

В любом случае, это не имеет смысла, используя ConcurrentQueue, если у вас недостаточно места для размещения 32 объектов...