gpt4 book ai didi

c# - 使用 Monitor.Wait 和 Monitor.Pulse 时出现内存不足异常

转载 作者:太空宇宙 更新时间:2023-11-03 21:22:47 29 4
gpt4 key购买 nike

我正在研究 .NET 中的 Monitor 类,所以我找到了一段似乎可以正常工作的代码,但是当我将它循环一段时间时,它会抛出 OutOfMemoryException

我在具有 8 GB RAM 的 64 位 Windows 8 开发人员计算机上运行此程序,并且我的进程从未占用超过 100 MB 的 RAM 空间。

这是我的代码:

    using System;
using System.Threading;

public class Program
{
public static void Main()
{
while (true) {

object theLock = new Object();
Thread threadA = new Thread(() =>
{
Console.WriteLine("Thread A before lock");
lock (theLock)
{
Console.WriteLine("Thread A locking, about to Wait");
Monitor.Wait(theLock);
}
Console.WriteLine("Thread A after lock");
});

Thread threadB = new Thread(() =>
{
Console.WriteLine("Thread B before lock");
lock (theLock)
{
Console.WriteLine("Thread B lockint, about to Pulse");
Monitor.Pulse(theLock);
}
Console.WriteLine("Thread B before lock");
});

threadA.Start();
threadB.Start();

GC.Collect();

}
}
}

我读了here这可能是一个碎片问题,我在最后添加了 GC.Collect()。但是我没有分配大块空间。

然后我决定测量循环在抛出异常之前大约经历了多少次迭代并添加了一个计数器:

    using System;
using System.Threading;

public class Program
{
public static void Main()
{
int counter = 0;

while (true) {
Console.WriteLine(counter);
counter++;

object theLock = new Object();
Thread threadA = new Thread(() =>
{
Console.WriteLine("Thread A before lock");
lock (theLock)
{
Console.WriteLine("Thread A locking, about to Wait");
Monitor.Wait(theLock);
}
Console.WriteLine("Thread A after lock");
});

Thread threadB = new Thread(() =>
{
Console.WriteLine("Thread B before lock");
lock (theLock)
{
Console.WriteLine("Thread B lockint, about to Pulse");
Monitor.Pulse(theLock);
}
Console.WriteLine("Thread B before lock");
});

threadA.Start();
threadB.Start();

GC.Collect();

}
}
}

这似乎大大减慢了异常的抛出速度。我测量了 36000 次迭代。

最佳答案

对于每对线程,如果线程 A 设法在线程 B 之前获取锁,您将以两个线程都完成而告终,并且可以清除所有内容。

如果线程 B 设法在线程 A 之前获取锁,则线程 B 将完成(已向监视器发出脉冲)但随后线程 A 将获取监视器并永远等待某个东西向它发出脉冲。所以到那时你将拥有:

  • 一个线程对象
  • 一个操作系统线程
  • 线程正在等待的对象

...基本上,所有这些都永远捆绑在一起。

鉴于此,我对您遇到问题并不感到惊讶。

不清楚您要达到的目标,但这可以解释症状。永远不要假设仅仅因为您在 threadB.Start() 之前调用了 threadA.Start(),第一个线程实际上会在第二个线程之前到达代码中的特定点。

关于c# - 使用 Monitor.Wait 和 Monitor.Pulse 时出现内存不足异常,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29541666/

29 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com