以文本方式查看主题

-  中文XML论坛 - 专业的XML技术讨论区  (http://bbs.xml.org.cn/index.asp)
--  『 Dot NET,C#,ASP,VB 』  (http://bbs.xml.org.cn/list.asp?boardid=43)
----  Whidbey 中对 GC 的功能两点增强  (http://bbs.xml.org.cn/dispbbs.asp?boardid=43&rootid=&id=11801)


--  作者:admin
--  发布时间:11/9/2004 2:26:00 AM

--  Whidbey 中对 GC 的功能两点增强


发信人: flier (小海 [寻找风车中]), 信区: DotNET
标  题: Whidbey 中对 GC 的功能两点增强
发信站: BBS 水木清华站 (Fri Mar 26 09:14:50 2004), 转信

http://61.155.107.18/user8/flier_lu/main.asp?id=1452116

Whidbey 中对 GC 的功能两点增强

    Brad Abrams在其blog中发表了一篇介绍Whidbey 中对 GC 的功能增强的文章Teaching an old dog new tricks: GC fun in Whidbey。其中提到两种对Unmanaged Resource的管理的GC增强。Justin Rogers则在其blog中回应前文,提出了一些很有趣的观点The new face of the GC in Whidbey... I'm not sure this is a pretty face...。

    新增的GC.AddMemoryPressure函数和GC.RemoveMemoryPressure函数可以提示GC当前Unmanaged资源的使用情况,以便GC判断在合适的时候进行回收工作;以前供WinForm内部使用的HandleCollector类也公开允许用户使用,用于管理Unmanaged资源的自动回收。

    对于CLR/JVM这种使用垃圾回收机制的环境,如何处理其无法管理的外部资源类型是一件让人头痛的事情。例如在使用Win32的位图(BITMAP)资源时,在Managed对象中只需保存一个句柄,但实际上内存占用跟位图文件大小相关,同时句柄本身的数量也是受到系统本身限制的。而这些Unmanaged资源对GC来说都是不可见的,GC只能看到这座冰山露出水面的一小部分,其余的部分只能靠程序员自觉管理,如使用Dispose模式。但这样的使用就违背了GC的基本原则,必然会出现两种内存管理模型的冲突。Whidbey中新增的这两个GC的增强,实际上就是分别对这两种内存管理模型,
提供了与GC兼容的接口。

    GC.AddMemoryPressure函数和GC.RemoveMemoryPressure函数是全局性统计的函数,它们必须被使用到Unmanaged资源的CLR对象成对地调用,以保障对资源使用情况的精确跟踪。如果一个对象忘记调用RemoveMemoryPressure函数,则此对象和其Unmanaged资源在被施放后,GC认为以前用AddMemoryPressure函数注册的Unmanaged资源仍在使用,会降低GC的准确率。因此最好使用mihailik给出的封装类UnmanagedResource,通过IDispose和Finalizer确保两个函数的匹配调用。

以下为引用:

public abstract class UnmanagedResource : IDisposable
{
  readonly int m_PressureAmount;

  public UnmanagedResource(int pressureAmount)
    : this( pressureAmount, true )
  { }


  public UnmanagedResource(int pressureAmount, bool addPressureNow)
  {
    this.m_PressureAmount=pressureAmount;

    if( addPressureNow )
      ResourceAllocated();
  }

  protected void ResourceAllocated()
  {
    GC.AddMemoryPressure(PressureAmount);
  }

  protected void ResourceReleased()
  {
    GC.RemoveMemoryPressure(PressureAmount);
  }


  protected int PressureAmount
  {
    get { return m_PressureAmount; }
  }


  public void Dispose()
  {
    Dispose(true);
  }

  protected virtual void Dispose(bool disposing)
  {
    ResourceReleased();

    if( disposing )
    {
      GC.SuppressFinalize();
    }
  }

  ~UnmanagedResource()
  {
    Dispose(false);
  }
}
  



    不过个人认为这种提示的管理粒度过大了,而且过于依赖人的自觉性。不如使用IoC模式的思想,定义一个接口IUnmanagedResource,所有使用Unmanaged资源的类都实现此接口,然后GC提供GC.RegisterForUnmanagedResource函数将对象注册到GC。此接口提供GetUnmanagedResourceSize()函数,让GC了解其Unmanaged资源的使用情况,如

以下为引用:

public interface IUnmanagedResource
{
  uint GetUnmanagedResourceSize();

};

class Bitmap : IUnmanagedResource
{
   private long _size;

   uint GetUnmanagedResourceSize()
   {
     return _size;
   }

   Bitmap (string path )
   {
      _size = new FileInfo(path).Length;

      GC.RegisterForUnmanagedResource(this);

      // other work
   }
}
  



    这样的好处是可以将对Unmanaged资源的管理粒度降低到对象一级,并让CLR对象和Unmanaged资源绑定,确保施放CLR对象时能够同步更新整体资源使用情况的统计数据,代价是GC需要维护一个和Finalizer列表类似的UnmanagedResource列表。
    在实现上GC.AddMemoryPressure函数和GC.RemoveMemoryPressure函数更新由GC的一个子类MemoryWatcher维护的几个统计值,并根据一定的策略触发GC的回收条件。

    System.Runtime.InteropServices.HandleCollector实现则比较简单,构造函数中指定阈值,自身维护一套计数器,在超出指定范围后回收句柄。使用方法很简单,如下:

以下为引用:

// HandleCollector(string name, int initialThreshold,  int maximumThreshold);

class XXX
{
  static readonly HandleCollector GdiHandleType =
     new HandleCollector( “GdiHandles”, 10, 50);

  static IntPtr CreateSolidBrush()
  {
     IntPtr temp = CreateSolidBrushImpl(…);

     GdiHandleType.Add();

     return temp;
  }



  internal static void DeleteObject(IntPtr handle)
  {
     DeleteObjectImpl(handle);

     GdiHandleType.Remove();
  }
}
  



   有兴趣的朋友可以进一步看看这个例子:
    http://www.gotdotnet.com/userfiles/chrisan/HandleCollector.zip
--
.    生命的意义在于   /\   ____\ /\_ \   /\_\    http://flier_lu.blogone.net.                            .  
.        希望         \ \  \___/_\/\ \   \/_/__     __    _ _★              .  
.        工作          \ \   ____\\ \ \    /\  \  /'__`\ /\`'_\              .  
.      爱你的人         \ \  \___/ \ \ \___\ \  \/\ __// \ \ \/              .  
.     和你爱的人         \ \___\    \ \_____\ \__\ \____\ \ \_\              .  
.        ……             \/___/     \/_____/\/__/\/____/  \/_/ @nsfocus.com.  


※ 来源:·BBS 水木清华站 smth.org·[FROM: 211.167.254.*]
上一篇
返回上一页
回到目录
回到页首
下一篇



W 3 C h i n a ( since 2003 ) 旗 下 站 点
苏ICP备05006046号《全国人大常委会关于维护互联网安全的决定》《计算机信息网络国际联网安全保护管理办法》
3,608.887ms