[英]Out of memory exception while playing with Monitor.Wait and Monitor.Pulse
我正在使用.NET中的Monitor类,因此我到达了一段似乎正常的代码,但是当我循环一段代码时,它抛出了OutOfMemoryException
。
我在具有8 GB RAM的64位Windows 8开发人员计算机上运行此程序,而我的进程从不占用RAM上100 MB以上的空间。
这是我的代码:
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();
}
}
}
我在这里阅读到这可能是碎片问题,并在最后添加了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将获取监视器,并永远等待某些东西来触发它。 因此,此时您将拥有:
Thread
对象 ...基本上,所有这些都永远捆绑在一起。
鉴于此,对于您遇到问题,我并不感到惊讶。
目前尚不清楚您要实现的目标,但这可以解释症状。 不要假设只是因为你叫threadA.Start()
之前threadB.Start()
第一个线程实际上第二个线程之前到达代码的某个点。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.