c#内存不足问题

jylee7 2014-12-31 02:04:05
主程序是运行图像处理的算法,然后将结果更新到主界面的label上,整个程序内存占用大概400M,程序跑上20多个小时后在更新label时会报内存不足,但根据日志记录的情况整个程序的内存占用并没有增加,内存剩余量也还有2G多,不知有没有大神能帮忙分析下可能是什么情况?
另外算法的运行是单独开线程的,界面更新这边出错后,算法那边仍然在正常跑。
错误信息:
Out of memory.
at System.Drawing.TextureBrush..ctor(Image image, WrapMode wrapMode)
at System.Windows.Forms.ControlPaint.DrawBackgroundImage(Graphics g, Image backgroundImage, Color backColor, ImageLayout backgroundImageLayout, Rectangle bounds, Rectangle clipRect, Point scrollOffset, RightToLeft rightToLeft)
at System.Windows.Forms.Control.PaintBackground(PaintEventArgs e, Rectangle rectangle, Color backColor, Point scrollOffset)
at System.Windows.Forms.Control.PaintBackground(PaintEventArgs e, Rectangle rectangle)
at System.Windows.Forms.Control.OnPaintBackground(PaintEventArgs pevent)
at System.Windows.Forms.ScrollableControl.OnPaintBackground(PaintEventArgs e)
at System.Windows.Forms.Control.PaintTransparentBackground(PaintEventArgs e, Rectangle rectangle, Region transparentRegion)
at System.Windows.Forms.Control.PaintBackground(PaintEventArgs e, Rectangle rectangle, Color backColor, Point scrollOffset)
at System.Windows.Forms.Control.PaintBackground(PaintEventArgs e, Rectangle rectangle)
at System.Windows.Forms.Control.OnPaintBackground(PaintEventArgs pevent)
at System.Windows.Forms.ScrollableControl.OnPaintBackground(PaintEventArgs e)
at System.Windows.Forms.Control.PaintTransparentBackground(PaintEventArgs e, Rectangle rectangle, Region transparentRegion)
at System.Windows.Forms.Control.PaintBackground(PaintEventArgs e, Rectangle rectangle, Color backColor, Point scrollOffset)
at System.Windows.Forms.Control.PaintBackground(PaintEventArgs e, Rectangle rectangle)
at System.Windows.Forms.Control.OnPaintBackground(PaintEventArgs pevent)
at System.Windows.Forms.Control.PaintWithErrorHandling(PaintEventArgs e, Int16 layer)
at System.Windows.Forms.Control.WmPaint(Message& m)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.Label.WndProc(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.OnMessage(Message& m)
at System.Windows.Forms.Control.ControlNativeWindow.WndProc(Message& m)
at System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
...全文
1054 17 打赏 收藏 转发到动态 举报
写回复
用AI写文章
17 条回复
切换为时间正序
请发表友善的回复…
发表回复
jylee7 2015-01-06
  • 打赏
  • 举报
回复
对我来说对界面的更改只有修改label的text属性,不知为何会导致out of memory,运行时界面也没让他最小化,感觉和隐藏没关系
qldsrx 2015-01-04
  • 打赏
  • 举报
回复
引用 15 楼 jylee7 的回复:
如果是内存泄漏导致的,照理说从任务管理器里是应该能看到程序内存占用的增加吧?但程序本身的内存占用也并没有增加,之前还测试过一次跑了10来天也没出错。报这个Out Of Memory在测试过程中总共就看到过两次
你是否考虑过桌面程序的最小化,隐藏的情况?也就是说,当程序看不到的时候,就不要去刷新界面了,也许那个时候会出现问题,这个是系统问题,至少我就发现过,一个定时用的桌面控制程序,开着啥都不做,也不刷新界面,几天后,窗口自己变形了,但我设置的不可控制大小的。
jylee7 2015-01-03
  • 打赏
  • 举报
回复
引用 14 楼 qldsrx 的回复:
既然你的程序跑了20多个小时后才报内存不足,那说明程序本身应该不会有严重的错误,不然不会要那么久才报。 一般长时间才报内存不足的,就要考虑是否存在内存泄露的情况了,内存泄露是看不到的,不属于程序使用中的内存。对于你的图像处理过程,很有可能是Image对象未做释放导致的,Image内部包含了非托管数据,用完必须调用Dispose方法而不能直接把引用去掉。
如果是内存泄漏导致的,照理说从任务管理器里是应该能看到程序内存占用的增加吧?但程序本身的内存占用也并没有增加,之前还测试过一次跑了10来天也没出错。报这个Out Of Memory在测试过程中总共就看到过两次
qldsrx 2015-01-02
  • 打赏
  • 举报
回复
既然你的程序跑了20多个小时后才报内存不足,那说明程序本身应该不会有严重的错误,不然不会要那么久才报。 一般长时间才报内存不足的,就要考虑是否存在内存泄露的情况了,内存泄露是看不到的,不属于程序使用中的内存。对于你的图像处理过程,很有可能是Image对象未做释放导致的,Image内部包含了非托管数据,用完必须调用Dispose方法而不能直接把引用去掉。
qldsrx 2015-01-01
  • 打赏
  • 举报
回复
你的内存剩余量也还有2G多,是指可用数还是单单看内存占比?必须看可用数才行,可用数为0就不足了。windows的内存显示往往不准确,我经常看到内存使用率为35%的时候,MySql报内存不足,此时系统缓存3G多,可用数为0
jylee7 2015-01-01
  • 打赏
  • 举报
回复
引用 7 楼 Z65443344 的回复:
当前时间和内存占用,你直接以字符串形式输出不就好了,变成图片作甚
是以字符形式啊,就改的label的text属性,报错后label变成红叉了
jylee7 2015-01-01
  • 打赏
  • 举报
回复
引用 12 楼 github_22161131 的回复:
如果这个背景图片是Image.FromStream创建的,那么那个stream也不能关闭,否则就会出现out of memory异常。这个很容易自己重现,而且异常栈和你给出的一样。所以我说很可能是这种原因。
背景图片的导入部分代码是vs自动生成的,在Form.Designer.cs里面 this.BackgroundImage = ((System.Drawing.Image)(resources.GetObject("$this.BackgroundImage"))); 这个也会出现你说的这种问题吗?我也没手动关过stream,不知如何重现呢?
winnowc 2015-01-01
  • 打赏
  • 举报
回复
如果这个背景图片是Image.FromStream创建的,那么那个stream也不能关闭,否则就会出现out of memory异常。这个很容易自己重现,而且异常栈和你给出的一样。所以我说很可能是这种原因。
jylee7 2015-01-01
  • 打赏
  • 举报
回复
引用 10 楼 github_22161131 的回复:
at System.Drawing.TextureBrush..ctor(Image image, WrapMode wrapMode) 这个地方报的out of memory应该是典型的gdi+的错误,这种out of memory自己都能重现,不是真正的内存不足。很可能是你给某个control指定了背景图片,但是这个背景图片在什么地方被dispose了。
界面是有张背景图片,但初始化完了后就再没动他了,这样他也会出错吗?
引用 9 楼 qldsrx 的回复:
你的内存剩余量也还有2G多,是指可用数还是单单看内存占比?必须看可用数才行,可用数为0就不足了。windows的内存显示往往不准确,我经常看到内存使用率为35%的时候,MySql报内存不足,此时系统缓存3G多,可用数为0
其实我还是怀疑不是真正的内存不足,而是别的原因导致的,因为真的内存不足那整个程序都应该挂掉,但现在是只挂了那个label更新的进程。
winnowc 2015-01-01
  • 打赏
  • 举报
回复
at System.Drawing.TextureBrush..ctor(Image image, WrapMode wrapMode) 这个地方报的out of memory应该是典型的gdi+的错误,这种out of memory自己都能重现,不是真正的内存不足。很可能是你给某个control指定了背景图片,但是这个背景图片在什么地方被dispose了。
於黾 2014-12-31
  • 打赏
  • 举报
回复
当前时间和内存占用,你直接以字符串形式输出不就好了,变成图片作甚
jylee7 2014-12-31
  • 打赏
  • 举报
回复
更新的内容不一样,出错的那两个更新的不是算法结果,是一些系统信息,像当前时间、内存占用情况,而且这两个更新频率更低,大概0.5秒1次
於黾 2014-12-31
  • 打赏
  • 举报
回复
既然用线程的方式没有问题,为什么不都用线程,弄2个放timer里是想做实验吗
jylee7 2014-12-31
  • 打赏
  • 举报
回复
因为程序没崩溃,结果更新到4个label,其中两个出错变成红叉了,另两个还在正常更新结果。 出错的那两个是通过form里的定时器更新的,没出错的那两个是算法线程里通过Form.Invoke来更新的
於黾 2014-12-31
  • 打赏
  • 举报
回复
你怎么知道程序崩溃的时候是界面更新有问题而不是图像处理的线程崩溃了?
jylee7 2014-12-31
  • 打赏
  • 举报
回复
引用 1 楼 Z65443344 的回复:
Out of memory不一定是内存不足,它其实是"内存溢出" 你可以执行如下代码试试: int[,] i=new int[20000,20000]; 检查你出错时处理的图像,是否像素数过多了
界面更新和图像处理是不同线程,而且图像处理的那个线程一直能正常运行,是不是能说明算法那边应该没有问题?
於黾 2014-12-31
  • 打赏
  • 举报
回复
Out of memory不一定是内存不足,它其实是"内存溢出" 你可以执行如下代码试试: int[,] i=new int[20000,20000]; 检查你出错时处理的图像,是否像素数过多了

110,539

社区成员

发帖
与我相关
我的任务
社区描述
.NET技术 C#
社区管理员
  • C#
  • Web++
  • by_封爱
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

让您成为最强悍的C#开发者

试试用AI创作助手写篇文章吧