我使用 EMGU+OpenCV 已经有一段时间了,遇到了这个AccessViolationException
谜团。
首先,代码:
class AVE_Simulation
{
public static int Width = 7500;
public static int Height = 7500;
public static Emgu.CV.Image<Rgb, float>[] Images;
static void Main(string[] args)
{
int N = 50;
int Threads = 5;
Images = new Emgu.CV.Image<Rgb, float>[N];
Console.WriteLine("Start");
ParallelOptions po = new ParallelOptions();
po.MaxDegreeOfParallelism = Threads;
System.Threading.Tasks.Parallel.For(0, N, po, new Action<int>((i) =>
{
Images[i] = GetRandomImage();
Console.WriteLine("Prossing image: " + i);
Images[i].SmoothBilatral(15, 50, 50);
GC.Collect();
}));
Console.WriteLine("End");
}
public static Emgu.CV.Image<Rgb, float> GetRandomImage()
{
Emgu.CV.Image<Rgb, float> im = new Emgu.CV.Image<Rgb, float>(Width, Height);
float[, ,] d = im.Data;
Random r = new Random((int)DateTime.Now.Ticks);
for (int y = 0; y < Height; y++)
{
for (int x = 0; x < Width; x++)
{
d[y, x, 0] = (float)r.Next(255);
d[y, x, 1] = (float)r.Next(255);
d[y, x, 2] = (float)r.Next(255);
}
}
return im;
}
}
代码很简单。分配一组图像。生成随机图像并用随机数填充它。对图像执行双边过滤。而已。
如果我在单个线程中执行该程序,(Threads=1)一切似乎都可以正常工作,没有问题。但是,如果我将并发线程数增加到 5,我会很快收到 AccessViolationException。
我检查了 OpenCV 代码并验证了 OpenCV 端没有分配,还检查了 EMGU 代码搜索未固定的对象或其他问题,一切似乎都是正确的。
一些注意事项:
- 如果你删除它,
GC.Collect()
你会得到AccessViolationException
更少的东西,但它最终会发生。 - 这仅在发布模式下执行时才会发生。在调试模式下,我没有遇到任何异常。
- 虽然每个图像是 675MB,但分配没有问题(我有 ALLOT 内存),并且
OutOfMemoryException
在系统内存不足的情况下会抛出一个 ' '。 - 我使用了双边过滤器,但其他过滤器/功能也出现了这个异常。
任何帮助,将不胜感激。一个多星期以来,我一直在努力解决这个问题。
i7 (无超频), Win7 64bit, 32GB RAM, VS 2010, Framework 4.0, OpenCV 2.4.3
堆:
Start
Prossing image: 20
Prossing image: 30
Prossing image: 40
Prossing image: 0
Prossing image: 10
Prossing image: 21
Unhandled Exception: System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
at Emgu.CV.CvInvoke.cvSmooth(IntPtr src, IntPtr dst, SMOOTH_TYPE type, Int32 param1, Int32 param2, Double param3, Double param4)
at TestMemoryViolationCrash.AVE_Simulation.<Main>b__0(Int32 i) in C:\branches\1.1\TestMemoryViolationCrash\Program.cs:line 32
at System.Threading.Tasks.Parallel.<>c__DisplayClassf`1.<ForWorker>b__c()
at System.Threading.Tasks.Task.InnerInvokeWithArg(Task childTask)
at System.Threading.Tasks.Task.<>c__DisplayClass10.<ExecuteSelfReplicating>b__f(Object param0)
at System.Threading.Tasks.Task.Execute()
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot)
at System.Threading.Tasks.Task.ExecuteEntry(Boolean bPreventDoubleExecution)
at System.Threading.Tasks.ThreadPoolTaskScheduler.TryExecuteTaskInline(Task task, Boolean taskWasPreviouslyQueued)
at System.Threading.Tasks.TaskScheduler.TryRunInline(Task task, Boolean taskWasPreviouslyQueued)
at System.Threading.Tasks.Task.InternalRunSynchronously(TaskScheduler scheduler, Boolean waitForCompletion)
at System.Threading.Tasks.Parallel.ForWorker[TLocal](Int32 fromInclusive, Int32 toExclusive, ParallelOptions parallelOptions, Action`1 body, Action`2 bodyWithState, Func`4 bodyWithLocal, Func`1 loc
alInit, Action`1 localFinally)
at System.Threading.Tasks.Parallel.For(Int32 fromInclusive, Int32 toExclusive, ParallelOptions parallelOptions, Action`1 body)
at TestMemoryViolationCrash.AVE_Simulation.Main(String[] args) in C:\branches\1.1\TestMemoryViolationCrash\Program.cs:line 35
Unhandled Exception: System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
at Emgu.CV.CvInvoke.cvSmooth(IntPtr src, IntPtr dst, SMOOTH_TYPE type, Int32 param1, Int32 param2, Double param3, Double param4)
at TestMemoryViolationCrash.AVE_Simulation.<Main>b__0(Int32 i) in C:\branches\1.1\TestMemoryViolationCrash\Program.cs:line 32
at System.Threading.Tasks.Parallel.<>c__DisplayClassf`1.<ForWorker>b__c()
at System.Threading.Tasks.Task.InnerInvokeWithArg(Task childTask)
at System.Threading.Tasks.Task.<>c__DisplayClass10.<ExecuteSelfReplicating>b__f(Object param0)
at System.Threading.Tasks.Task.Execute()
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot)
at System.Threading.Tasks.Task.ExecuteEntry(Boolean bPreventDoubleExecution)
at System.Threading.ThreadPoolWorkQueue.Dispatch()
Unhandled Exception: System.AccessViolationException: Attempted to read or write protected memory. This is often an indication that other memory is corrupt.
at Emgu.CV.CvInvoke.cvSmooth(IntPtr src, IntPtr dst, SMOOTH_TYPE type, Int32 param1, Int32 param2, Double param3, Double param4)
at TestMemoryViolationCrash.AVE_Simulation.<Main>b__0(Int32 i) in C:\branches\1.1\TestMemoryViolationCrash\Program.cs:line 32
at System.Threading.Tasks.Parallel.<>c__DisplayClassf`1.<ForWorker>b__c()
at System.Threading.Tasks.Task.InnerInvokeWithArg(Task childTask)
at System.Threading.Tasks.Task.<>c__DisplayClass10.<ExecuteSelfReplicating>b__f(Object param0)
at System.Threading.Tasks.Task.Execute()
at System.Threading.ExecutionContext.RunInternal(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state, Boolean preserveSyncCtx)
at System.Threading.Tasks.Task.ExecuteWithThreadLocal(Task& currentTaskSlot)
at System.Threading.Tasks.Task.ExecuteEntry(Boolean bPreventDoubleExecution)
at System.Threading.ThreadPoolWorkQueue.Dispatch()
Press any key to continue . . .