2012-02-13 31 views
0

我有懷疑,這部分代碼會導致內存泄漏:如何檢測內存泄露

public FileResult ShowCroppedImage(int id, int size) 
    { 
     string path = "~/Uploads/Photos/"; 
     string sourceFile = Server.MapPath(path) + id + ".jpg"; 

     MemoryStream stream = new MemoryStream(); 
     var bitmap = imageManipulation.CropImage(sourceFile, size, size); 
     bitmap.Save(stream, System.Drawing.Imaging.ImageFormat.Jpeg); 
     Byte[] bytes = stream.ToArray(); 
     return File(bytes, "image/png"); 
    } 

我如何才能讓看到一個測試,如果這段代碼是什麼原因?

編輯:

public Image CropImage(string sourceFile, int newWidth, int newHeight) 
     { 
      Image img = Image.FromFile(sourceFile); 
      Image outimage; 

      int sizeX = newWidth; 
      int sizeY = newHeight; 

      MemoryStream mm = null; 

      double ratio = 0; 
      int fromX = 0; 
      int fromY = 0; 

      if (img.Width < img.Height) 
      { 
       ratio = img.Width/(double)img.Height; 
       newHeight = (int)(newHeight/ratio); 
       fromY = (img.Height - img.Width)/2; 
      } 
      else 
      { 
       ratio = img.Height/(double)img.Width; 
       newWidth = (int)(newWidth/ratio); 
       fromX = (img.Width - img.Height)/2; 
      } 
      if (img.Width == img.Height) 
       fromX = 0; 

      Bitmap result = new Bitmap(sizeX, sizeY); 

      //use a graphics object to draw the resized image into the bitmap 
      Graphics grPhoto = Graphics.FromImage(result); 

      //set the resize quality modes to high quality 
      grPhoto.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality; 
      grPhoto.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic; 
      grPhoto.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality; 
      //draw the image into the target bitmap 
      //now do the crop    
      grPhoto.DrawImage(
       img, 
       new System.Drawing.Rectangle(0, 0, newWidth, newHeight), 
       new System.Drawing.Rectangle(fromX, fromY, img.Width, img.Height), 
       System.Drawing.GraphicsUnit.Pixel); 


      // Save out to memory and get an image from it to send back out the method. 
      mm = new MemoryStream(); 
      result.Save(mm, System.Drawing.Imaging.ImageFormat.Jpeg); 
      img.Dispose(); 
      result.Dispose(); 
      grPhoto.Dispose(); 
      outimage = Image.FromStream(mm); 

      return outimage; 
     } 
+2

簡單的方法:鑽機您的程序重複調用的代碼,然後看你在任務管理器進程。如果使用的內存不斷增加並且永遠不會下降,那麼你有泄漏。 – Blorgbeard 2012-02-13 23:29:51

+2

http://mitch-wheat.blogspot.com.au/2010/11/determine-if-your-net-application-has.html – 2012-02-13 23:30:36

+1

,你可以在這裏做的唯一一件事就是包裹的MemoryStream到使用塊處置它會自動。你爲什麼認爲有任何內存泄漏。請讓我們知道imageManipulation.CropImage裏面有什麼。你關閉非託管手柄嗎? – abhishek 2012-02-13 23:31:26

回答

3

我將它寫成

public FileResult ShowCroppedImage(int id, int size) 
{ 
    string path = "~/Uploads/Photos/"; 
    string sourceFile = Server.MapPath(path) + id + ".jpg"; 

    using (MemoryStream stream = new MemoryStream()) 
    { 
     using (Bitmap bitmap = imageManipulation.CropImage(sourceFile, size, size)) 
     { 
      bitmap.Save(stream, System.Drawing.Imaging.ImageFormat.Jpeg); 
      Byte[] bytes = stream.ToArray(); 
      return File(bytes, "image/png"); 
     } 
    } 
} 

確保stream.Dispose & bitmap.Dispose被調用。

+0

的'使用(MemoryStream的= ...)'只是儀式,周圍的位圖的使用似乎更相關。 – 2012-02-13 23:51:56

+1

@HenkHolterman,是儀式,但是一個好習慣。 – 2012-02-13 23:54:24

+2

處理任何實施IDisposable的東西,當你不再需要它時總是很好的做法。如果在實踐中只是因爲其他實現需要這種能力,那麼無關緊要;如果它是IDisposable,請處置它。 – KeithS 2012-02-14 00:11:35

0

可能要Byte[] bytes = stream.ToArray();之後調用stream.dispose();

0

考慮到的問題是如何檢測內存泄漏/使用情況,我建議你在寫之前和之後調用你的函數記錄存儲器利用的方法:

public void SomeTestMethod() 
{ 
    var before = System.GC.GetTotalMemory(false); 
    // call your method 
    var used = before - System.GC.GetTotalMemory(false); 
    var unreclaimed = before - System.GC.GetTotalMemory(true); 
} 

之前之前將測量內存使用您的函數運行。所使用的變量將保存你的函數在垃圾回收器運行之前使用了多少內存,並且未回收會告訴你即使在嘗試清理對象後,你的函數使用了多少個字節。

我懷疑用過會很高,沒有聲稱不會 - 在你的記憶流中放置一個使用,因爲其他海報建議應該使它們更近一些,但要記住,你仍然有一個字節數組保持內存。