为什么我会发生OutOfMemoryException?
问题描述:
我有这种方法,我从计时器滴答事件每X秒调用方法。 在开始的几秒钟内没有任何问题,但是在20秒后或者显示异常。为什么我会发生OutOfMemoryException?
private void ReturnTexture(Texture texture_take, List<Point> lstPnt, float[] anglArr, float angle)
{
int i, j, bytes = 2048 * 512, stride = 2048;
GraphicsStream textureStream;
byte[] rgbValues = new byte[bytes];
//sets texture to complete transparent
GCHandle gch = GCHandle.Alloc(rgbValues, GCHandleType.Pinned);
MemSet(gch.AddrOfPinnedObject(), 0x0, rgbValues.Length);
//add 90 degrees because the cone starts at 90
angle += 90F + 23.75F;
//checks all points and draws yellow only those how are inside the cone
if (lstPnt != null)
{
for (i = 0; i < lstPnt.Count - 1; i++)
{
if (anglArr[i] <= angle && anglArr[i] >= angle - 47.5F) //if point angle is inside cone. Cone angle is 47.5 degrees
{
j = lstPnt[i].Y * stride + lstPnt[i].X * 4;
//yellow
rgbValues[j + 0] = (byte)0;
rgbValues[j + 1] = (byte)255;
rgbValues[j + 2] = (byte)255;
rgbValues[j + 3] = (byte)255;
}
else
{
}
}
}
唯一的例外是上线:
byte[] rgbValues = new byte[bytes];
当异常发生,我看到变量字节包含:1048576 而rgbValues是空
我异常之前使用断点发生并看到以字节为单位的值是相同的:1048576但异常仅在20秒左右后才发生,而不仅仅是在开始时。
类型 '的System.OutOfMemoryException' 的未处理的异常发生在天气Radar.exe
System.OutOfMemoryException was unhandled
HResult=-2147024882
Message=Exception of type 'System.OutOfMemoryException' was thrown.
Source=Weather Radar
StackTrace:
at Weather_Radar.Form1.ReturnTexture(Texture texture_take, List`1 lstPnt, Single[] anglArr, Single angle) in d:\C-Sharp\Weather Radar\Weather Radar\Weather Radar\Form1.cs:line 314
at Weather_Radar.Form1.timer1_Tick(Object sender, EventArgs e) in d:\C-Sharp\Weather Radar\Weather Radar\Weather Radar\Form1.cs:line 59
at System.Windows.Forms.Timer.OnTick(EventArgs e)
at System.Windows.Forms.Timer.TimerNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.DebuggableCallback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
at System.Windows.Forms.UnsafeNativeMethods.DispatchMessageW(MSG& msg)
at System.Windows.Forms.Application.ComponentManager.System.Windows.Forms.UnsafeNativeMethods.IMsoComponentManager.FPushMessageLoop(IntPtr dwComponentID, Int32 reason, Int32 pvLoopData)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoopInner(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.ThreadContext.RunMessageLoop(Int32 reason, ApplicationContext context)
at System.Windows.Forms.Application.Run(Form mainForm)
at Weather_Radar.Program.Main() in d:\C-Sharp\Weather Radar\Weather Radar\Weather Radar\Program.cs:line 19
at System.AppDomain._nExecuteAssembly(RuntimeAssembly assembly, String[] args)
at System.AppDomain.ExecuteAssembly(String assemblyFile, Evidence assemblySecurity, String[] args)
at Microsoft.VisualStudio.HostingProcess.HostProc.RunUsersAssembly()
at System.Threading.ThreadHelper.ThreadStart_Context(Object state)
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.ExecutionContext.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException:
314线在Form1是:字节[] rgbValues =新的字节[字节];
form1中的第59行是:ReturnTexture(scannedCloudsTexture,cloudPoints,angleArray,angleF);
这是计时器滴答事件代码:
static float angle_ = 0.0F;
static float angleF = 0.0F;
private void timer1_Tick(object sender, EventArgs e)
{
if (angleF > 360F)
{
angleF -= 360F;
}
ReturnTexture(scannedCloudsTexture, cloudPoints, angleArray, angleF);
DisplayOnScreen(angle_);
angle_ += (float)(Math.PI * 1d/180d);
angleF += 1.0F;
}
答
正如Renuiz在评论解释说,它看起来像你不释放分配给你的形象记忆。当你拨打GCHandle.Alloc
一个新的GCHandle保护对象免受垃圾回收。当GCHandle不再需要时,必须使用Free发布。
如果你不Free
GCHandle
,你的代码分配的1MB将永远不会被释放。我认为有两种可能的选择:
- 如果可能,重新使用
byte[]
,不需要更多的内存。保留GCHandle
,以便您可以将它们memset以使每个勾号归零。 - 请勿使用
GCHandle
将byte[]
固定在内存中。反正你创建一个新的byte[]
all values will be set to zero。
的GCHandle免受垃圾收集器,所以你应该释放内存使用调用GCHandle.Free方法,当手柄没有更多必要 – InferOn 2014-09-30 07:20:19
我敢打赌,每个时钟滴答您的RAM增加。尝试重复使用您的数组,而不是在每次打勾时创建 – Reniuz 2014-09-30 07:21:27