2012-01-28 35 views
2

whileループでコードを実行して、プログラムが常に実行されていることを確認しています。プログラムは、プログラムがバックアップからコピーし、それがないし、それを開始した場合、それは、それを起動する実行されていない場合は、空想何も:whileループでのメモリリーク

while (true) 
{ 
    Process backup = new Process(); 
    ProcessStartInfo check = new ProcessStartInfo(file); 
    if (Process.GetProcessesByName(file).Length == 0) 
    { 
     if(File.Exists(file)) 
     { 
      backup.StartInfo = check; 
      backup.Start(); 
     } 
     else if (!File.Exists(file)) 
     { 
      File.Copy(backupFile, file); 
      Thread.Sleep(250); 
      backup.StartInfo = check; 
      backup.Start(); 
     } 
    } 
    backup.Close(); 
    Thread.Sleep(2000); 
} 

問題は各サイクルの後ではありませんRAM使用量が上がります私が知っていることはあまりありませんが、これが1時間ほど実行されていれば、それは大きな問題を引き起こすでしょう。

私はそれを一時停止しようとしましたが、プロセス上で.Close()を使用しましたが、喜んではありませんでした。どんなアイデアも高く評価されています。

+4

あなたはメモリリークがあると思いますか?データが収集できない(実際のメモリリークがある)かどうかをGCが収集するのを待っていますか? – ken2k

+0

5行目に実際に文字列リテラルを使用していますか、それともタイプミスですか? – Nuffin

+0

申し訳ありませんが、入力ミス。 –

答えて

10
  1. プロセスが実行されていない場合を除き、それらが実行されないようにif文の内部でこれらの行を入れてください:

    Process backup = new Process(); 
    ProcessStartInfo check = new ProcessStartInfo(file); 
    
  2. ProcessIDisposableを実装しているので、あなたがオデッドとして、usingステートメントでそれをラップすることができます提案する。

  3. 実際のメモリリークはありません。ガベージコレクタが実行されると、メモリが再利用されます。一時的なメモリ使用量が問題であれば、GCを強制的に実行することができますが、一度すれば一時的なメモリ使用量に問題はありません。

0

投稿したコードにはメモリリークはありません。

あなたは、ガベージコレクタ自分でこれは一般的に悪いデザインとみなされ、あなたは絶対にRAMの量を制御する必要があればあなたはこれだけを使用する必要があること

System.GC.Collect(); 

注意を使用して反復のすべてのX量を起動しようとすることができます使っている。 このようなハードリソース要件がある場合は、いずれの場合でもC#が選択された言語にならないことがあります。

+2

強く反対します。ほとんどの場合、明示的に収集するようにGCに依頼しないでください(実際には99%)。 – ken2k

+0

はい、次のループはスコープの外に前回のインスタンス化を行い、メモリは残っていますが、とにかくGCedする必要があります – Jeb

+0

私は完全に同意し、OPコードに(上記のように)しかし、OPが2秒ごとに100k刻みで関心を持つ場合、彼らはGC自体を呼び出すことができます。私は、低リソース環境など、必要な場合の1%のためにこのオプションを提供していました。 – ose

0

多くのことが言われているように、実際にはメモリリークはありません(少なくともそれはそのようには見えません)。

しかし、初期化をどこかで行うことができます。バックアップを初期化し、必要がないときにチェックすることがよくあります。

while (true) 
{ 
    Process backup; 
    ProcessStartInfo check; 
    if (Process.GetProcessesByName(file).Length == 0) 
    { 
     check = new ProcessStartInfo(file);//moved init 
     backup = new Process();//moved init 
     if(File.Exists(file)) 
     { 
      backup.StartInfo = check; 
      backup.Start(); 
     } 
     else if (!File.Exists(file)) 
     { 
      File.Copy(backupFile, file); 
      Thread.Sleep(250); 
      backup.StartInfo = check; 
      backup.Start(); 
     } 
    } 
    backup.Close(); 
    Thread.Sleep(2000); 
} 
+0

変数の宣言を実際の使用に近いものにする必要があります。 – ken2k

+0

問題はバックアップが条件付きの外で参照されていることです。 – rtpg

-1

私は同じ問題を抱えていたので、私はこれを使用:

[DllImport("KERNEL32.DLL", EntryPoint = "SetProcessWorkingSetSize", SetLastError = true, CallingConvention = CallingConvention.StdCall)] 
internal static extern bool SetProcessWorkingSetSize(IntPtr pProcess, int dwMinimumWorkingSetSize, int dwMaximumWorkingSetSize); 

[DllImport("KERNEL32.DLL", EntryPoint = "GetCurrentProcess", SetLastError = true, CallingConvention = CallingConvention.StdCall)] 
internal static extern IntPtr GetCurrentProcess(); 

は、これらのメソッドを呼び出して、メモリが解放されます。

-1

Look !,私はこれらのオプションをすべて確認しましたが、何もしませんでした。一方、私はあなたの問題を解決しました。 Create新しいスレッドのApartmentState = STAを設定して、その中にあるコードをこの新しいスレッドで実行するようにします。これを使用すると、すべてのリソースがスレッドの破棄後に解放されます。私はそれを試して、それは動作します!