垃圾收集器不会释放某些对象的内存

时间:2013-05-19 22:36:24

标签: c# garbage-collection

我有这些方法:

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

在执行带有612KB GetImage文件的JPEG之后,我的应用程序的内存消耗量增加了10MB,即使在几分钟之后,这些10MB内存也没有被丢弃。

  • 如何确定GetImage生成的对象将是 符合GC条件?
  • 如何确保生成的对象 方法执行后,GetImage将不会被分配很长时间?

1 个答案:

答案 0 :(得分:3)

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

由于您的JPEG是一个大型对象,因此GC不会将其放入Gen1收集器中,后者比其他更长寿命的收集器清理得更多。因此,收集压力的可能性更小。

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

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