【发布时间】:2019-01-22 07:40:26
【问题描述】:
下面是一个简单的控制台应用程序代码,它反复触发异步调用但不等待。被调用的函数抛出异常。 运行此控制台应用程序会产生以下结果:
- 在调试器下的 VS 中 - 内存使用量持平。没有泄漏。
- 直接运行 exe(在 vs 之外而不是在调试器下)- 内存不断增长到 gbs,最终 OOM 约为 4gb。
我不知道如何解释这些结果。任何帮助将不胜感激。
static void Main(string[] args)
{
while (true)
{
Task.Run(() => RunMain());
}
Console.ReadLine();
}
static Exception ex = new Exception();
private static void RunMain()
{
throw ex;
}
编辑: 我主要对为什么连续抛出未观察到的异常时内存泄漏感兴趣。
【问题讨论】:
-
很好奇。我现在不能自己测试这个,但是对于观察到的行为是否需要多个并发线程抛出相同且唯一的 Exception 对象实例?或者当每个任务创建自己的异常实例时也会发生同样奇怪的行为?
-
我认为它在调试和发布模式下都会泄漏,即使您捕获了异常。但是,使用 附加调试器,您的代码运行速度要慢得多,因此它可能看起来很平坦,但实际上并非如此。如果您从诊断工具放大到进程内存。真奇怪。如果您收集第 0 代,它不会泄漏。 GC 无法正常工作。
-
@elgonzo - 不,这不是必需的。但我这样做只是为了消除创建新异常对象太多次的可能性。当每个任务都创建自己的异常时,会观察到相同的行为。
-
@M.kazemAkhgary - 你说得对,它在调试和发布模式下都会泄漏。关于减慢泄漏的调试器 - 这是可能的。当然,我的主要兴趣是弄清楚为什么会泄漏,而不是为什么在调试器下它会这么慢。
标签: c# .net task-parallel-library clr