while循环中的内存泄漏

时间:2012-01-28 11:38:06

标签: c# memory-management while-loop

我在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的使用量增加了大约100KB,这并不是我所知道的很多,但是如果它运行了一个小时左右就会造成很大的问题。

我尝试暂停它并在过程中使用.Close()但没有快乐。任何想法都非常感激。

5 个答案:

答案 0 :(得分:10)

  1. 将这些行放在if语句中,这样就不会执行它们,除非进程没有运行:

    Process backup = new Process();
    ProcessStartInfo check = new ProcessStartInfo(file);
    
  2. 由于Process实现IDisposable,您可以将其包装在using语句中,如Oded建议的那样。

  3. 您没有实际的内存泄漏。垃圾收集器运行时,内存将被回收。如果临时内存使用有问题,您可以强制GC运行,但我认为一旦您执行#1,您也不会遇到临时内存使用问题。

答案 1 :(得分:0)

您发布的代码中没有内存泄漏。

您可以尝试使用

每X次迭代自己调用垃圾收集器
System.GC.Collect();

请注意,这通常被认为是糟糕的设计,所以如果您绝对需要控制正在使用的RAM量,则应该只使用它。 在任何情况下,如果您有这样的硬资源要求,C#可能不是首选语言。

答案 2 :(得分: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);
}

答案 3 :(得分:-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();

调用这些方法,内存将被释放。

答案 4 :(得分:-1)

看!我刚检查了所有这些选项,但没有。另一方面,我解决了你的问题。创建一个新的线程设置其ApartmentState = STA,然后将您在while内部的代码放在这个新线程上执行。使用它,您将确保在线程销毁后将释放所有资源。我测试了它,它有效!