Warning: file_get_contents(/data/phpspider/zhask/data//catemap/7/image/5.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 内存泄漏通过图像循环到字节数组_C#_Image_Memory Leaks_Bytearray - Fatal编程技术网

C# 内存泄漏通过图像循环到字节数组

C# 内存泄漏通过图像循环到字节数组,c#,image,memory-leaks,bytearray,C#,Image,Memory Leaks,Bytearray,我有一个例行程序,扫描文件夹中的图像,然后针对每个图像,将其转换为缩略图,然后将缩略图上载到数据库。只有在数据库中没有该特定文件夹的任何项目时,它才会运行。我的问题是,我在处理了几个文件夹后收到内存不足异常,我不确定泄漏发生在哪里。我已经尝试过处理循环中的所有可丢弃的东西,但很明显有些东西仍然从裂缝中掉落 private bool LoadImages(int folderid, int parentid) { ProgressScreen tfrm = new ProgressScreen

我有一个例行程序,扫描文件夹中的图像,然后针对每个图像,将其转换为缩略图,然后将缩略图上载到数据库。只有在数据库中没有该特定文件夹的任何项目时,它才会运行。我的问题是,我在处理了几个文件夹后收到内存不足异常,我不确定泄漏发生在哪里。我已经尝试过处理循环中的所有可丢弃的东西,但很明显有些东西仍然从裂缝中掉落

private bool LoadImages(int folderid, int parentid) {
  ProgressScreen tfrm = new ProgressScreen();
  tfrm.Hide();
  DataTable mtable = new DataTable();
  List<FileInfo> lfile;
  mtable = Requests.ProcessSQLCommand(sqlconn, "Select f.ID, f.FolderName,f.FolderPath,f.ParentID,f.Root from Folders f where f.ID = " + folderid);
  DataTable ptable = Requests.ProcessSQLCommand(sqlconn, "Select Root from Folders where ID = " + parentid);
  if (ptable != null && ptable.Rows.Count > 0) {
    if (ptable.Rows[0]["Root"].ToString().ToLower() == "true") {
      return false;
    }
  }
  bool process = true;
  DirectoryInfo di = new DirectoryInfo(mtable.Rows[0]["FolderPath"].ToString());
  FileInfo[] smFiles = di.GetFiles("*.jpg", SearchOption.TopDirectoryOnly);
  lfile = smFiles.ToList<FileInfo>();
  if (lfile.Count <= 0) {
    process = false;
  }
  if (process) {
    tfrm.Show(this);
    for (int c = 0; c < lfile.Count; c++) {
      if (((FileInfo)lfile[c]).Extension == ".txt") {
        lfile.RemoveAt(c);
      }
      if (((FileInfo)lfile[c]).FullName.ToLower().Contains("cover")) {
        lfile.RemoveAt(c);
      }
    }
      for (int b = 0; b < lfile.Count; b++) {
        Cursor.Current = Cursors.WaitCursor;
        this.Enabled = false;
        try {
          tfrm.Location = new Point((Screen.PrimaryScreen.WorkingArea.Width / 2) - (tfrm.Width / 2), (Screen.PrimaryScreen.WorkingArea.Height / 2) - (tfrm.Height / 2));
        } catch {
        }
        tfrm.SetProgress((int)(((double)(b + 1) / (double)lfile.Count) * 100), "Loading Images", lfile[b].Name.ToString());
        tfrm.Refresh();
        int recid = 0;
        DataTable ttable = Requests.ProcessSQLCommand(sqlconn, "Insert into Image (Name,FolderID,ParentID) VALUES ('" + lfile[b].Name + "'," + folderid + "," + parentid + ") Select SCOPE_IDENTITY()");
        if (ttable != null && ttable.Rows.Count > 0) {
          recid = int.Parse(ttable.Rows[0][0].ToString());
        }
        if (recid > 0) {
          Image timg = null;
          byte[] traw = new byte[0];
          traw = File.ReadAllBytes(lfile[b].FullName);
          MemoryStream tstream = new MemoryStream(traw);
          timg = System.Drawing.Image.FromStream(tstream);
          tstream.Dispose();
          timg = Requests.FixedSize(timg, 600, 600);
          tstream = new MemoryStream();
          timg.Save(tstream, System.Drawing.Imaging.ImageFormat.Png);
          timg.Dispose();
          traw = new byte[0];
          traw = tstream.ToArray();
          tstream.Dispose();
          System.Data.SqlClient.SqlConnection con = new System.Data.SqlClient.SqlConnection(sqlconn);
          con.Open();
          System.Data.SqlClient.SqlCommand cmd = new System.Data.SqlClient.SqlCommand("Update Image set [Thumb] = Convert(VarBinary(MAX),@Image) where ID = " + recid, con);
          cmd.Parameters.AddWithValue("@Image", traw);
          cmd.ExecuteNonQuery();
          con.Dispose();
        }
      }
    this.Enabled = true;
    Cursor.Current = Cursors.Default;
    tfrm.Close();
    tfrm.Dispose();
    System.Windows.Forms.Application.UseWaitCursor = false;
    return true;
  } else {
    return false;
  }
}
private bool LoadImages(int-folderid,int-parentid){
ProgressScreen tfrm=新的ProgressScreen();
tfrm.Hide();
DataTable mtable=新DataTable();
列表文件;
mtable=Requests.ProcessSQLCommand(sqlconn,“从文件夹f中选择f.ID、f.FolderName、f.FolderPath、f.ParentID、f.Root,其中f.ID=“+folderid”);
DataTable ptable=Requests.ProcessSQLCommand(sqlconn,“从ID=“+parentid”的文件夹中选择根目录);
如果(ptable!=null&&ptable.Rows.Count>0){
if(ptable.Rows[0][“Root”].ToString().ToLower()=“true”){
返回false;
}
}
布尔过程=真;
DirectoryInfo di=new DirectoryInfo(mtable.Rows[0][“FolderPath”].ToString());
FileInfo[]smFiles=di.GetFiles(“*.jpg”,SearchOption.TopDirectoryOnly);
lfile=smFiles.ToList();
如果(lfile.Count 0){
recid=int.Parse(ttable.Rows[0][0].ToString());
}
如果(recid>0){
图像timg=null;
字节[]traw=新字节[0];
traw=File.ReadAllBytes(lfile[b].FullName);
MemoryStream tstream=新的MemoryStream(traw);
timg=System.Drawing.Image.FromStream(tstream);
tstream.Dispose();
timg=请求.固定大小(timg,600600);
tstream=新内存流();
保存(tstream,System.Drawing.Imaging.ImageFormat.Png);
timg.Dispose();
traw=新字节[0];
traw=tstream.ToArray();
tstream.Dispose();
System.Data.SqlClient.SqlConnection con=new System.Data.SqlClient.SqlConnection(sqlconn);
con.Open();
System.Data.SqlClient.SqlCommand cmd=new System.Data.SqlClient.SqlCommand(“更新图像集[Thumb]=Convert(VarBinary(MAX),@Image),其中ID=“+recid,con”);
cmd.Parameters.AddWithValue(“@Image”,traw);
cmd.ExecuteNonQuery();
con.Dispose();
}
}
this.Enabled=true;
Cursor.Current=Cursors.Default;
tfrm.Close();
tfrm.Dispose();
System.Windows.Forms.Application.UseWaitCursor=false;
返回true;
}否则{
返回false;
}
}
固定尺寸法:

public static Image FixedSize(Image imgPhoto, int Width, int Height) {
  int sourceWidth = imgPhoto.Width;
  int sourceHeight = imgPhoto.Height;
  int sourceX = 0;
  int sourceY = 0;
  int destX = 0;
  int destY = 0;

  float nPercent = 0;
  float nPercentW = 0;
  float nPercentH = 0;

  nPercentW = ((float)Width / (float)sourceWidth);
  nPercentH = ((float)Height / (float)sourceHeight);
  if (nPercentH < nPercentW) {
    nPercent = nPercentH;
    destX = System.Convert.ToInt16((Width - (sourceWidth * nPercent)) / 2);
  } else {
    nPercent = nPercentW;
    destY = System.Convert.ToInt16((Height - (sourceHeight * nPercent)) / 2);
  }

  int destWidth = (int)(sourceWidth * nPercent);
  int destHeight = (int)(sourceHeight * nPercent);

  Bitmap bmPhoto = new Bitmap(Width, Height, PixelFormat.Format24bppRgb);
  bmPhoto.SetResolution(imgPhoto.HorizontalResolution, imgPhoto.VerticalResolution);

  Graphics grPhoto = Graphics.FromImage(bmPhoto);
  grPhoto.Clear(Color.Magenta);
  grPhoto.InterpolationMode = InterpolationMode.HighQualityBicubic;
  grPhoto.DrawImage(imgPhoto, new Rectangle(destX, destY, destWidth, destHeight), new Rectangle(sourceX, sourceY, sourceWidth, sourceHeight), GraphicsUnit.Pixel);

  grPhoto.Dispose();
  return bmPhoto;
}
公共静态图像固定大小(图像imgPhoto、int-Width、int-Height){
int sourceWidth=imgPhoto.Width;
int sourceHeight=imgPhoto.Height;
int sourceX=0;
int sourceY=0;
int destX=0;
int destY=0;
浮动百分比=0;
浮动nPercentW=0;
浮点数nPercentH=0;
nPercentW=((浮点)宽度/(浮点)源宽度);
nPercentH=((浮动)高度/(浮动)源高度);
如果(nPercentH
原始图像(固定大小之前)的范围从2MB到20MB不等,返回的图像(表中的最大值(len(image))约为750 KB。(编辑:更正的文件大小)

每个文件夹的图像数~100-150


我已经查看并调试过,但找不到导致OOM问题的原因,是否有人可以指出错误,或者为我正在做的事情提供更好的优化?

如果这是一个代码审查,我会建议对代码进行许多改进。。。 但无论如何,特别是针对您的问题..您的内存泄漏发生在以下代码行中(请不要将其视为个人问题,但很难发现,因为代码没有那么干净)


这里有2
timg
。一个是原始的,第二个是从
请求中得到的。FixedSize
。你传递给
请求的
timg
。FixedSize
没有得到处理。

你可能不是内存不足,而是资源不足。那里有很多东西需要处理ich应该被处理,但可能不会。您可以通过任务管理器查看GDI对象和句柄。FWIW,使用将仔细清理代码。您拥有的最大映像的维度是什么?您是否以32位运行此代码?它是否总是在特定映像上爆炸?正如@VikasGupta指出的,100MB JPG几乎是可以保证的d导致OOM(甚至可能在x64上)由于未压缩图像的大小。@VikasGupta最大的图像是18.3MB 3744x6516x24b,程序编译为64位。不,它不是一个特定的图像,通常是在处理了大约20到30个文件夹之后。在处理了大约100个文件夹之后,它似乎保存得很好。使用Process Explorer,其他控件上似乎还有其他漏洞,但它可能与您发现的相似。
      timg = System.Drawing.Image.FromStream(tstream);
      tstream.Dispose();
      timg = Requests.FixedSize(timg, 600, 600);
      ....
      timg.Dispose();