2016-08-17 9 views
0

.netコンソールアプリケーションを介して頻繁に実行される無限のタスクを実装しています。しかし、私は、以下がメモリリークを招くことに懸念しています。 Mainは静的なので(これはガベージコレクションに関する私の知識が霧になる)、メインが終了するまでガベージコレクタによって取り込まれることはありません。メインメソッドからのガベージコレクション(無限ループ)

この場合、ガーベッジコレクタがどのように動作するか説明してください。

public static void Main(string[] args) 
    { 
     Log.Logger = new LoggerConfiguration() 
     .MinimumLevel.Debug() 
     .WriteTo.RollingFile("Logs/log-{Date}.txt") 
     .CreateLogger(); 
     while (true) 
     { 
      try 
      { 
       Thread.Sleep(1000); 
       new UpdatePlayer().Run(); 
      } 
      catch (Exception ex) 
      { 
       Log.Error(ex.ToString()); 
      } 
     } 
    } 

答えて

1

あなたは何のメモリリークがないよ:メモリリークと

... 
try 
{ 
    Thread.Sleep(1000); 

    // Instance created, executed 
    new UpdatePlayer().Run(); 
} 

// And can be safely collected here when the instance is out of scope (`try {...}`) 
// the anonymous instance can't be accessed and that's enough 

サンプル

// please notice, that anchor is outside the `while(true)` scope 
List<Object> anchor = new List<Object>(); 
... 

while (true) 
{ 
     try 
     { 
     Thread.Sleep(1000); 

     // Instance created 
     var item = new UpdatePlayer(); 
     // anchored 
     anchor.Add(item); 
     // and executed 
     item.Run();   
     } 

     // item can't be collected here: anchor has a reference to it 
     // And the item potentially can be accessed by, say, anchor[0] 

Mainはありませ任意の参照インスタンスUpdatePlayer()を編集し、コレクションをに移動すると

 try 
     { 
     List<object> pseudoAnchor = new List<object>(); 

     // Instance created 
     var item = new UpdatePlayer(); 
     // tried to be anchored (illusion) 
     pseudoAnchor.Add(item); 
     // and executed 
     item.Run();   
     } 
     ... 

     // the only reference to item is pseudoAnchor, but 
     // pseudoAnchor has not been referenced, and so GC 
     // can safely collect entire pseudoAnchor with all its items 
     // (just one `item` in fact) 
+0

これは本当に良い例です。 tryブロックを終了するとコレクションが発生しますか? – DeanR

+1

@DeanR:コレクションを 'try'スコープに移動した場合:' try {List anchor = new List (); ...} 'コードはメモリリークなし*になります。もう一度:GCは*コレクション全体を集めることができます*。 –

2

主な(ガベージコレクションの私の知識は霧取得する場所これは)静的であるので、それは私がしようとするとキャッチの中に作成したオブジェクトがガベージコレクタによってピックアップされないことを意味するものではありませんメインが終了するまで(これは決してありません)?

いいえ、それは偽です。

ガベージコレクタは、マネージコードからアクセスできなくなったことが証明できるオブジェクトのメモリを解放できます。この場合、Runメソッドが終了した後(そのオブジェクトへの参照を他の場所に保存しない限り)、そのオブジェクトはアクセスできなくなり、GCが解放できるようになります(これを行うには時間がかかることは明らかです、それはが許可されています)。

+0

GCはそれを解放することにしたんどの時点で:スコープは、コードがなしでメモリリークでしょうか?試し終えたら? – DeanR

+1

@DeanRいつでも、それはしたい、または決して。文字通りいつでもアクセスできなくなってから、時間が終わる前に。 – Servy