创建大量线程时的.Net内存泄漏问题

8

我有一个应用程序,随着时间的推移创建了很多线程。我注意到随着它的运行,内存使用量会增加,并最终耗尽内存。但是,在我同事的环境中,相同的代码不会泄漏内存。我们两个都有相同的.net版本。我能够使用以下示例代码重现此问题,但这在我同事的笔记本电脑上不会泄漏。

public static void Main(string[] args)
{           
    Console.WriteLine("Version " + Environment.Version.ToString());

    if (Environment.Is64BitProcess) 
        Console.WriteLine("64"); 
    else 
        Console.WriteLine("32");

    while(true)
    {
        Thread t = new Thread(() => { Thread.Sleep(1); });
        t.IsBackground = true;
        t.Start();
        Thread.Sleep(1);               
    }
}

当我运行以上代码时,它会打印出以下内容。
Version 4.0.30319.18063
32

在Visual Studio 2012中,项目的目标框架是.NET Framework 4.5。 该项目在以下配置下泄露内存。
Project Properties -> Build
    Platform target: Any CPU
    Prefer 32-bit: checked

如果我取消勾选“偏好32位”,它就不会泄漏。
另一个泄露内存的配置是:
Project Properties -> Build
    Platform target: x86
    Prefer 32-bit: disabled

我的笔记本电脑上泄漏的可执行文件在我的同事的笔记本电脑上没有泄漏。

我使用CLR Profiler查找内存泄漏,但它没有显示任何泄漏的内容。但我看到在Windows资源监视器中工作集每秒增加大约1 MB。

是什么导致32位模式下我的环境中的内存使用量增加,但我的同事的环境中没有?


1
就我个人而言,当我在我的电脑上尝试这个操作时,我得到的结果与你的同事一样(没有泄漏)。 - Cameron
2
您IP地址为143.198.54.68,由于运营成本限制,当前对于免费用户的使用频率限制为每个IP每72小时10次对话,如需解除限制,请点击左下角设置图标按钮(手机用户先点击左上角菜单按钮)。 - usr
1
@usr:我检查了线程,它们大约有5个,而且数量没有增加。 - Csharp_user
2
我真的很期待看到这个问题解决。 - Thomas Weller
4
以前你可以通过这样的代码相当可靠地让你的程序崩溃。Thread类使用了很多句柄但却没有Dispose()方法。微软做了些改变,现在不行了。你需要寻找其他种类的软件,这些软件对句柄过于感兴趣,比如那些程序员自愿安装在他们机器上的包装恶意软件。关闭你的防病毒产品并重试。 - Hans Passant
显示剩余22条评论
2个回答

0

我已经阅读了所有的评论,担心我的评论会被忽略,所以我来回答一下。

使用专为.NET应用程序设计的内存分析器,如JetBrains dotMemory或ANTS,而不是WinDBG、任务管理器或其他本地内存工具。

您可以使用所选分析器的实时图表比较应用程序在您和同事的笔记本电脑上的行为。我猜您会发现,在您的笔记本电脑上,内存使用量不断增加 - 只需获取内存快照,查看有多少个线程对象在内存中,哪些对象占用了大部分内存,并调查它们为什么被保留在内存中以及由谁保留。


-2

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接