【发布时间】:2011-05-21 18:26:12
【问题描述】:
我这里有一些代码
private void Run()
{
MyClass c = new MyClass();
c.Load(somepath1);
using (StreamReader sr = new StreamReader(filepath))
{
string line = string.Empty;
while ((line = sr.ReadLine()) != null)
{
using (Bitmap B = new Bitmap(line))
{
Point p = SomeMethod(ref c, new Point());
using (MemoryStream ms = new MemoryStream())
{
B.Save(ms, System.Drawing.Imaging.ImageFormat.Bmp);
using (Bitmap T = new Bitmap(new Bitmap(Image.FromStream(ms))))
using (Graphics g = Graphics.FromImage(T))
{
g.DrawEllipse(new Pen(Brushes.Red, 4), p.X - 5, p.Y - 5, 10, 10);
FileInfo fi = new FileInfo(somepath2);
T.Save(Path.Combine(somepath3, fi.Name));
}
}
}
}
}
}
函数 SomeMethod 是:
Point SomeMethod(ref MyClass c, Point mid)
{
float[] Mat = new float[9];
Point p;
c.Method1(Mat);
c.Method2(Mat, out p);
return p;
}
我的班级是:
public class MyClass
{
public void Method1(float[] Mat, out Point point)
{
//calculation point from values in Mat
}
public void Method2(float[] Mat)
{
//Do some Operation in Mat
}
public void Load(string FileName)
{
//Do Some Data Loading From a small file about 400 byte
}
}
StreamReader sr 在文件路径中打开一个包含大约 400 行图像位置的文件,我读取它们并根据我的计算在它们上绘制一些东西,我没有使用任何外部库或任何不安全的代码。 问题是为什么我的内存不足??
-------------编辑--------
当程序启动时它使用大约 20mb 的内存,在调用 Run 之后内存使用量开始增加,如果我运行它大约 200 张图像,内存大约 1.7Gb 并且 Run 函数完成工作并且内存使用量回到 20mb
------------编辑------------ 在 MemoryStream 中保存位图 B 是因为图形不能使用索引像素格式的图像。 主要问题是垃圾收集器在这里做什么? 我没有应该保留在内存中的对象。
---------编辑----
例外是:
System.OutOfMemoryException was unhandled
Message=Out of memory.
Source=System.Drawing
StackTrace:
at System.Drawing.Graphics.CheckErrorStatus(Int32 status)
at System.Drawing.Graphics.DrawImage(Image image, Int32 x, Int32 y, Int32 width, Int32 height)
at System.Drawing.Bitmap..ctor(Image original, Int32 width, Int32 height)
at System.Drawing.Bitmap..ctor(Image original)
at WindowsFormsApplication1.Form1.buttonrun1_Click(Object sender, EventArgs e) in C:\Users\hamidp\Desktop\WindowsFormsApplication1\WindowsFormsApplication1\Form1.cs:line 115
at System.Windows.Forms.Control.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnClick(EventArgs e)
at System.Windows.Forms.Button.OnMouseUp(MouseEventArgs mevent)
at System.Windows.Forms.Control.WmMouseUp(Message& m, MouseButtons button, Int32 clicks)
at System.Windows.Forms.Control.WndProc(Message& m)
at System.Windows.Forms.ButtonBase.WndProc(Message& m)
at System.Windows.Forms.Button.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.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(Int32 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 WindowsFormsApplication1.Program.Main() in C:\Users\hamidp\Desktop\WindowsFormsApplication1\WindowsFormsApplication1\Program.cs:line 17
at System.AppDomain._nExecuteAssembly(Assembly 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.Run(ExecutionContext executionContext, ContextCallback callback, Object state)
at System.Threading.ThreadHelper.ThreadStart()
InnerException:
以及在行抛出的异常:
using (Bitmap T = new Bitmap(new Bitmap(Image.FromStream(ms))))
-------------------编辑-----------
我还在
之后添加了GC.Collect();这一行
while ((line = sr.ReadLine()) != null)
同样的错误再次发生。
【问题讨论】:
-
您的图片尺寸是多少?您使用的是什么操作系统(32/64 位)?你是为什么平台编译的?
-
Windows 7 Professional 64 位,图像约为 350KB jpeg,使用 Microsoft Visual Studio 2010,WinForms。
-
尝试在较小的子集上运行它,同时观察内存消耗。它会以指数方式爆炸,还是有痛阈?
-
它以某种方式线性增加,当它大约 2GB 时我的内存不足
-
JPEG 是一种压缩格式。当它被加载到内存中成为一个位图时,它将被解压缩到完整大小。 350K JPEG 可以在内存中扩展为 1MB 到 10MB 的位图,具体取决于图像的复杂性。图像的像素宽度和高度将告诉您每个图像在内存中需要多少内存(如果每像素 32 位,则 w * h * 4 字节)