【C# .Net GC】手动监视和控制对象的生命周期(GCHandle)

 

这个话题还未做详细研究,暂时用不到,只是粗略看了一下。

使用System.Runtime.InteropServices.GCHandle类来手动控制对象的生命周期

(个人感觉这里可能有一些问题...只是草稿而已..还请高手指正)

1.GCHandle.Alloc

  传递一个Object和一个GCHandleType枚举给Alloc方法以控制Object的生命周期,返回一个GCHandle

  1) GCHandleType.Weak 此标志位允许你监视对象生命周期,当对象被标记为不可到达的时候,这个对象的Finalize方法可能执行也可能没有执行,这个对象可能依然存在于内存中

  2) GCHandleType.WeakTrackResurrection 此标志位允许你监视对象生命周期,对象的Finalize方法肯定会被执行(如果有的话),内存会被回收

  3) GCHandleType.Nomal  此标志位允许你控制对象生命周期,保证对象一直存在,在GC的时候该对象可能被移动位置

  4) GCHandleType.Pinned  此标志位允许你控制对象生命周期,保证对象一直存在,在GC的时候该对象不会被移动

 

2.GC和GCHandle的关系

  GCHanlde 是一个轻量级的值类型,内部只包含一个实例Field:IntPtr

  1) GC标记所有可到达的对象,然后GC扫描 GC Handle 表, 所有标记为Normal和Pinned的对象将被视为可到达的对象(包括这些对象的成员 这是一个递归的过程)

  2) GC扫描GC Handle表中所有标记为Weak的实体,如果该实体所指向的Object被标记为不可到达的,(也就是标记为垃圾),那么这个拥有指针的实体将置为null

  3) GC扫描终结列表(Finalization List 不知道怎么翻译...),将所有指向不可到到达的指针移动到Freachable Queue,然后被指向的对象标记为可到达的

  4) GC扫描GC Handle 表中所有标记为WeakTrackResurrection 的实体,如果该实体所指向的Object被标记为不可到达的,那么拥有这个指针的实体将置为null

  5) GC Compact内存(当然有的时候GC不并执行这个动作,因为它觉得不值得),此外Pinned的对象不会被移动

3.应用

  1) c# fixed关键字 就是GCHandleType.Pinned 的实际应用之一

  2) Weak标记可以让你知道什么时候一个对象已经决定被回收,(但是这个对象也许还没有被回收)

  3) WeakTrackResurrection标记可以让你知道什么时候一个对象的内存被回收(按书中所说...这个东西好像没啥用)

  4) WeakReference其实就是对GCHandle的封装

posted @ 2022-02-28 21:22  小林野夫  阅读(1024)  评论(0编辑  收藏  举报
原文链接:https://www.cnblogs.com/cdaniu/