C# 在另一个线程中使用线程时会发生内存泄漏

C# 在另一个线程中使用线程时会发生内存泄漏,c#,multithreading,memory,memory-leaks,C#,Multithreading,Memory,Memory Leaks,下面的示例代码存在内存泄漏。如果我注释掉RefreshTimer_中的两行,那么内存泄漏就消失了。有人知道怎么了吗?谢谢你的帮助 static void RefreshTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e) { Thread innerThread = new Thread(delegate() { }); innerThread.Start(); }

下面的示例代码存在内存泄漏。如果我注释掉RefreshTimer_中的两行,那么内存泄漏就消失了。有人知道怎么了吗?谢谢你的帮助

    static void RefreshTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
    {
        Thread innerThread = new Thread(delegate() { });
        innerThread.Start();
    }

    static void Main(string[] args)
    {
        System.Timers.Timer RefreshTimer = new System.Timers.Timer();
        RefreshTimer.Interval = 5000;
        RefreshTimer.Elapsed += new System.Timers.ElapsedEventHandler(RefreshTimer_Elapsed);
        RefreshTimer.Start();

        for (; ; )
        { }           
    }

我认为这是因为你一直在创建新线程。

我认为这是因为你一直在创建新线程。

你确定内存泄漏吗?或者你注意到你的记忆力在增长吗

在垃圾收集器清除您创建的所有线程之前,内存将增长,但不会泄漏,垃圾收集器知道这是死内存

在.NET或java这样的托管环境中,内存“泄漏”的唯一方式是当引用的对象从未使用或需要时。这里不是这样。你只是在创建一堆线程,然后马上忘记它们。一旦它们不再被RefreshTimer\u引用,线程停止运行,那么就没有更多的引用,可以自由地清理它们


在垃圾收集器准备好进行清理之前,您不会看到内存下降。您可以尝试强制执行此操作,但出于性能原因,通常不建议这样做。

是否确实存在内存泄漏?或者你注意到你的记忆力在增长吗

在垃圾收集器清除您创建的所有线程之前,内存将增长,但不会泄漏,垃圾收集器知道这是死内存

在.NET或java这样的托管环境中,内存“泄漏”的唯一方式是当引用的对象从未使用或需要时。这里不是这样。你只是在创建一堆线程,然后马上忘记它们。一旦它们不再被RefreshTimer\u引用,线程停止运行,那么就没有更多的引用,可以自由地清理它们


在垃圾收集器准备好进行清理之前,您不会看到内存下降。您可以尝试强制执行此操作,但出于性能原因,通常不建议这样做。

您看到的可能只是垃圾收集器尚未回收的资源,因为没有内存压力

另外,在主例程中有一个忙for循环,您可能需要一个
线程.Sleep
语句用于测试,除非这是测试的一部分

要强制垃圾收集仅用于测试,您可以将for循环替换为:

while(true)
{
 Thread.Sleep(5000);
 GC.Collect();
 GC.WaitForPendingFinalizers();
}

一般来说,在检查托管代码中的“内存泄漏”或资源问题时,我建议使用探查器(即),并仔细查看一段时间内的分配情况。

您看到的可能只是垃圾收集器尚未回收的资源,因为没有内存压力

另外,在主例程中有一个忙for循环,您可能需要一个
线程.Sleep
语句用于测试,除非这是测试的一部分

要强制垃圾收集仅用于测试,您可以将for循环替换为:

while(true)
{
 Thread.Sleep(5000);
 GC.Collect();
 GC.WaitForPendingFinalizers();
}

通常,在检查托管代码中的“内存泄漏”或资源问题时,我建议使用探查器(即),并仔细查看随时间的分配情况。

需要处理计时器对象

需要处理计时器对象

您似乎正在创建新项,因为代码有一个递归调用,并且在运行时可能会出现某种循环,导致内存中充满了对象的多个副本,因为每个被调用的项都没有完全完成

您似乎正在创建新项,因为代码有一个递归调用,并且在运行时可能会出现某种循环,导致内存中充满了对象的多个副本,因为每个被调用的项都没有完全完成

RefreshTimer\u每间隔生成一个新线程。匿名方法在做什么工作?完成了吗?您创建的每个线程都将通过Windows获得1MB的虚拟内存


如果线程从未完成,那么每个间隔将消耗另外1MB的内存。

刷新计时器\u每个间隔生成一个新线程。匿名方法在做什么工作?完成了吗?您创建的每个线程都将通过Windows获得1MB的虚拟内存


如果线程从未完成,那么每间隔一次,您将再消耗1MB内存。

您是如何得出代码存在内存泄漏的结论的?您使用什么来确定泄漏?如何得出代码存在内存泄漏的结论?你用什么来确定泄漏?我认为询问者必须创建新的线程。如果未创建新线程,则下次调用innerThread.Start()时将引发ThreadStateException(“线程正在运行或终止;无法重新启动”)。@bitxwise:无论是否必须,不断创建某个内容不会导致内存泄漏吗?不……只有GC从未收集到它时才会被视为内存泄漏。@bitxwise:他没有说是,所以我认为不是。我认为询问者必须创建新线程。如果未创建新线程,则下次调用innerThread.Start()时将引发ThreadStateException(“线程正在运行或终止;无法重新启动”)。@bitxwise:无论是否必须,不断创建的内容不会导致内存泄漏吗?不……只有在GC从不收集它的情况下才会被视为内存泄漏。@bitxwise:他没有说是,所以我认为不是。GC.Collect();GC.WaitForPendingFinalizers();上述GC收集语句确实解决了“泄漏”。因此,“泄漏”看起来不像是真正的“泄漏”。谢谢。GC.Collect();GC.WaitForPendingFinalizers();上述GC收集语句确实解决了“泄漏”。因此,“泄漏”看起来不像是真正的“泄漏”。谢谢