nitrous_007 Ответов: 1

Почему массив объектов не освобождается после завершения области действия объекта?


У меня есть объект "class1object", который является членом class2. Я инициализирую его, как показано ниже.

class2{

class1 [] class1object1;

public class2()
{
 class1object1=new class1[1000000];
}

public void Start()
{
}
}
Я использую Class2object в другой функции Start в Class3 и вызываю ее 100 раз.


Class3
{
public static void Start()
{
      for(int i=0;i<100;i++)
    {  Class2 class2object=new Class2();
      class2object.Start();
     }
}
}

Наконец, функция Start в классе 3 вызывается из класса 4 как статический вызов.
Class4
{
  void Start()
{
   Class3.Start();
}

}
Теперь проблема, которую я вижу, - это массив class1object1, который я никогда не очищал и продолжает расти в памяти. Я использовал профилировщик Редгейт для наблюдателя это. размер class1object1 составляет 4 МБ, и при каждом запуске память, используемая этим объектом, увеличивается на 4 МБ. Почему сбор мусора не начинается в какой-то момент? Я запустил его до тех пор, пока он не использовал около 500 МБ памяти. В классе object1 нет неуправляемых членов, даже если он находится в небезопасном объекте кода.


Есть идеи или предложения?

Что я уже пробовал:

Я пробовал профилирования собой. Я пытался использовать неуправляемую память в c#, но не смог сделать этого с stackalloc, потому что мне нужно сохранить переменные в функции и передать их другой функции.

1 Ответов

Рейтинг:
4

Sergey Alexandrovich Kryukov

Короткий вопрос: это не то, как работает управление памятью. Я бы предположил, что ваше заблуждение проистекает из опыта работы в классическом старом C++, где выход за пределы области действия функции действительно приводит к разрушению.

В .NET вы имеете дело с управлением памятью на основе GC; и уничтожение объектов также основано на этой архитектуре. Разрушение и восстановление памяти основано на концепции достижимый или недостижимый ссылки, что является довольно сложным критерием. Когда какая-то ссылка становится недостижимой, следует разрушение объекта, но не сразу. Скорее всего, это происходит в соответствии с внутренним поведением GC; поэтому у вас нет контроля над моментом времени, когда вызывается деструктор и память восстанавливается. Вот почему деструкторы довольно редко пишутся в приложениях .NET.

Это объясняется, например, здесь: Сбор мусора (информатика) - Википедия, свободная энциклопедия.

Другая, связанная с этим проблема-проблема возможных утечек памяти. Прежде всего, "обнаружение" утечки памяти часто является ложноположительным наблюдением. Делаете ли вы свой вывод из Диспетчера задач Windows? Если это так, не доверяйте ему.

Утечки памяти все еще возможны, но вся концепция не так тривиальна. "Случайные" утечки, очень обычные из-за неуправляемых ошибок кода, очень маловероятны. Но они могут возникнуть из-за ошибок в общем дизайне кода. Я обсуждал эту проблему в своих прошлых ответах:
Лучший способ избавиться от публичного статического списка, вызывающего нехватку памяти,
отсрочка varirable внутри цикла может вызвать утечку памяти?,
Сборщик мусора заботится обо всем управлении памятью,
Управление памятью в формах MDI,
Утечка памяти в привязке данных WPF.

—СА


BillWoodruff

+5 отличный анализ

Sergey Alexandrovich Kryukov

- Спасибо, Билл.
—СА