2013-05-19 103 views
0

我有以下方法:垃圾收集器将某些对象的不自由内存

public void GetImage(JObject o) 
{ 
    var imageFile = o["file"].ToString(); 

    if (!File.Exists(imageFile)) 
    { 
     SendMessage("File does not exist"); 
     return; 
    } 

    using (var image = Image.FromFile(imageFile)) 
    { 
     var serialized = GetImageAsString(image); 

     var ob = new JObject 
       { 
        { COMMAND, (int) Command.GetImage }, 
        { "content", serialized } 
       }; 

      Send(ob); 
      ob = null; 
      serialized = null; 
    } 
} 

private static string GetImageAsString(Image image) 
{ 
    using (var stream = new MemoryStream()) 
    { 
      image.Save(stream, System.Drawing.Imaging.ImageFormat.Jpeg); 
      return Convert.ToBase64String(stream.ToArray()); 
    } 
} 

private static void Send(JObject o) 
{ 
    var package = EncodeContent(o); 
    _stream.Write(package, 0, package.Length); 
    _stream.Flush(); 

    Cursor.Current = Cursors.WaitCursor; 
} 

private static byte[] EncodeContent(JObject o) 
{ 
    return Encoding.UTF8.GetBytes(string.Concat(GetMessageSize(o), o, (char) 3)); 
} 

GetImage具有612KB JPEG文件执行后,我的应用程序的内存占用10MB去了,甚至几经分钟那些10MB不处理。

  • 我怎么能肯定的是,通过GetImage生成的对象将是 资格由GC
  • 如何确保 GetImage生成的对象在方法执行后不会被分配很长时间?
+2

如果你发出另一个GetImage,它会上升10MB吗?如果是这样,你可以在下降之前做多少次? –

+0

你有没有处置或重置'_stream'? –

+0

实现IDisposable将确保您的对象可以被GC访问,但.NET有一定的开销,所以我不会为此担心。如果你想精确控制内存的使用情况,.NET并不是最好的选择 – jugg1es

回答

3

GC确定自己何时释放内存 - 基本上当感觉压力释放内存时,它会这样做。如果它没有这样的压力,它不会。

由于您的JPEG是一个大对象,GC不会将它放入Gen1收集器中,这会比其他更长寿的世代更清洁。因此,收集压力的可能性更小。

要检查它是否因为不喜欢它而收集它,或者如果它是泄漏,请尝试执行以下一组调用,并查看您的内存会发生什么情况。如果它不下降,那么你可能有泄漏(尽管我猜测它只是GC不收集)。 (免责声明 - 我不建议你在代码中留下这些代码,让GC做它的事情)。

 GC.Collect(); 
     GC.WaitForPendingFinalizers(); 
     GC.Collect();