2012-02-13 3 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

+2

http://mitch-wheat.blogspot.com.au/2010/11/determine-if-your-net-application-has.html –

+1

여기서 할 수있는 것은 MemoryStream을 using 블록에 래핑하여 처리하는 것입니다 자동으로. 왜 메모리 누수가 있다고 생각하니? imageManipulation.CropImage 안에 무엇이 있는지 알려주세요. 관리되지 않는 핸들을 닫고 있습니까? – abhishek

답변

3

나는 stream.Dispose & bitmap.Dispose가 호출되도록

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"); 
     } 
    } 
} 

로 작성합니다.

+0

'using (MemoryStream = ...) '은 비트 맵 주위를 사용하는 것입니다. 더 관련성이있는 것 같습니다. –

+1

@HenkHolterman, 네,하지만 그것은 의식이지만 좋은 습관입니다. –

+2

더 이상 필요하지 않을 때 IDisposable을 구현하는 모든 것을 삭제하는 것은 항상 좋은 습관입니다. 실제로 다른 구현체가 그 능력을 필요로하기 때문에 그것은 중요하지 않습니다. IDisposable이면 처분하십시오. – KeithS

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); 
} 

당신의 기능이 실행됩니다. 사용 된 변수는 가비지 수집기가 실행되기 전에 함수가 사용한 메모리의 양을 보유하고 unreclaimed는 객체를 정리하려고 시도한 후에도 함수가 사용한 바이트 수를 알려줍니다.

내가 사용하는 것으로 의심되는 것은 높지 않고 언 클럭되지 않을 것입니다. 다른 포스터와 마찬가지로 메모리 스트림 주위에서 사용하는 것이 좋습니다. 그러나 메모리에 바이트 배열이 유지되는 것을 염두에 두십시오.