2016-07-15 1 views
-1

Я пытаюсь понять процесс сбора мусора, и я думаю, что у меня есть идея. Но когда я работаю над некоторыми кодами, он не работает, как я ожидал. В приведенном ниже коде я только что создал объект 1.000.000 и добавил их в список. Через некоторое время нет объекта, но память стирается и не уменьшается. Как я могу добиться освобождения памяти после удаления всех объектов?Освобождение памяти, используемой объектами и списками

Благодаря

 private void button1_Click(object sender, EventArgs e) 
    { 
     List<Test> tesst = new List<Test>(); 

     for (long i = 0; i < 1000000; i++) 
     { 
      using (Test test = new Test()) 
      { 

       test.LongObj = i; 
       test.StrObj = i.ToString(); 
       test.DecObj = Convert.ToDecimal(i); 
       tesst.Add(test); 
      } 
     } 
     Process proc = Process.GetCurrentProcess(); 
     proc.Refresh(); 
     label1.Text = Test.counter.ToString(); 
     label2.Text = (proc.PrivateMemorySize64/1048576).ToString(); 
     for (int i = 0; i < tesst.Count; i++) 
     { 
      tesst[i] = null; 
     } 
     tesst.Clear(); 
     tesst = null; 

    } 

    private void button2_Click(object sender, EventArgs e) 
    { 
     Process proc = Process.GetCurrentProcess(); 
     proc.Refresh(); 
     label1.Text = Test.counter.ToString(); 
     label2.Text = (proc.PrivateMemorySize64/1048576).ToString(); 
    } 

А класс образец

public class Test : IDisposable 
{ 
    public static long counter = 0; 

    public long LongObj { get; set; } 
    public string StrObj { get; set; } 
    public decimal DecObj { get; set; } 

    public Test() 
    { 
     Interlocked.Increment(ref counter); 
    } 

    ~Test() 
    { 
     Interlocked.Decrement(ref counter); 
    } 
    public void Dispose() 
    { 
    } 
} 

ответ

0

Почему именно вы пытаетесь освободить память вручную? Есть веские причины, но я хочу убедиться, что вы находитесь в ситуации, требующей этого.

Вы можете заставить сбор мусора вызывать GC.Collect() и необязательно с параметром, сообщающим, какое поколение собирать. Вы можете узнать больше об этом here, и он включает аналогичный тест на то, что вы пытаетесь сделать.

+0

Я выполняю некоторые операции в пакетном коде, и у меня проблемы с памятью. Вот почему я пытаюсь освободить память вручную. – PepeDeLew

+1

Это не будет веской причиной. Когда вы пытаетесь выделить память, и слишком много «давления в памяти» (т. Е. Память должна быть освобождена до выделения большего количества), GC позаботится об этом для вас. Это целая работа, чтобы справиться с этим для вас. Он очистит его прямо перед тем, как выделить вам больше памяти. Если вы получаете исключение, связанное с памятью, это гораздо лучший вопрос. В этом случае вы должны просто позволить этому сделать это. –

0

Как добиться освобождения памяти после удаления всех объектов?

У вас нет, вы позволяете GC выполнять свою работу. Принуждение сбора мусора (с использованием System.GC.Collect()) почти всегда является плохим.

+0

У меня проблемы с памятью в моих групповых операциях. Нормально ли, что деструктор называется, но использование памяти продолжается слишком долго? – PepeDeLew

+0

@TemporaryName Если у вас действительно есть проблемы с памятью, отправьте воспроизводимый пример, у вас может быть какая-то утечка памяти в вашем коде. 99,99% времени вам не придется вручную запускать сборку мусора. Также я не уверен, что вы называете «деструктором» (это не очень дружелюбное слово C#). Предполагая, что это финализатор, вы, вероятно, тоже не хотите его создавать, если у вас нет неуправляемых ресурсов. – ken2k

+0

Да. В рамках процесса сбора мусора предметы готовятся к сбору, маркируются как готовые к сбору, а затем собираются. Вызов финализатора _usually_ происходит на этапе подготовки к сборке. –

0

Это действительно похоже на сценарий, в котором вам нужно переосмыслить свой процесс. Я не думаю, что это работа для ручного взаимодействия с GC. Может быть, если вы разместите часть своего кода в другом вопросе, люди могут выкинуть некоторые идеи по-другому, чтобы решить проблему?

Смежные вопросы