国产精品电影_久久视频免费_欧美日韩国产激情_成年人视频免费在线播放_日本久久亚洲电影_久久都是精品_66av99_九色精品美女在线_蜜臀a∨国产成人精品_冲田杏梨av在线_欧美精品在线一区二区三区_麻豆mv在线看

.Net析構函數再論(源碼剖析)

開發 前端
一個對象需要進行空間的分配,當進行空間分配的時候,它會判斷當前函數是否包含了析構函數。如果包含了,則設置flags標志最后一位位1.然后在對象分配的時候,把它放入到析構隊列里面去。

1.前言

本篇繼續看下析構函數的一些引申知識。

2.概述

析構函數目前發現的總共有三個標記,這里分別一一介紹下。先上一段代碼:

internal class Program :  IDisposable{
     static void Main(string[] args){
         StreamReader? streamReader = null;
         streamReader = new StreamReader("Test_.dll");
         streamReader?.Dispose();
         Console.ReadLine();
     }
     ~Program(){
         Console.WriteLine("調用了析構函數");
     }
     public void Dispose(){
         this.Dispose();
         GC.SuppressFinalize(this);
     }
 }

這里的析構函數跟Dispose一起混用, ~Program()析構函數會通過Roslyn生成

.method family hidebysig virtual instance void 
        Finalize() cil managed
{
  .override [System.Runtime]System.Object::Finalize
  // 代碼大小       24 (0x18)
  .maxstack  1
  IL_0000:  nop
  .try
  {
    IL_0001:  nop
    IL_0002:  ldstr      bytearray (03 8C 28 75 86 4E 90 67 84 67 FD 51 70 65 )       // ..(u.N.g.g.Qpe
    IL_0007:  call       void [System.Console]System.Console::WriteLine(string)
    IL_000c:  nop
    IL_000d:  leave.s    IL_0017
  }  // end .try
  finally
{
    IL_000f:  ldarg.0
    IL_0010:  call       instance void [System.Runtime]System.Object::Finalize()
    IL_0015:  nop
    IL_0016:  endfinally
  }  // end handler
  IL_0017:  ret
} // end of method Program::Finalize

這里同時需要注意 streamReader?.Dispose();這句話,streamreader實際上繼承的是textreader

public class StreamReader : TextReader
{}

所以它調用Dispose的代碼是TextReader里面的Dispose:

public void Dispose()
 {
     Dispose(true);
     GC.SuppressFinalize(this);
 }

也就是關閉了streamReader流。然后base.Dispose.這個base.Dispose實際上就是它的父類TextReader里面的

public void Dispose()
{
   this._streamReader.close();
}

Dispose里面的下面一句代碼

GC.SuppressFinalize(this);

它是重點。

GC.SuppressFinalize

1.判斷當前類是否有析構函數

如果類里面有析構函數,比如例子里的Program,則會設置MethodTable的成員m_dwFlags

m_dwFlags |= enum_flag_HasFinalizer(0x00100000);

它的設置邏輯是如果存在析構函數,并且當前方法不是接口,不是虛方法,方法的索引小于當前類的索引數,當前的方法不是Object.Finlize()。那么說明當前這個類有析構函數,所以需要在當前類的MethodTable上進行操作,也即上面的m_dwFlags位設置。

邏輯代碼如下:

//存在析構函數,并且當前方法不是接口,不是虛方法
if (g_pObjectFinalizerMD && !IsInterface() && !IsValueClass())
{
    WORD slot = g_pObjectFinalizerMD->GetSlot();
    //方法的索引小于當前類宗的索引數,當前的方法不是Object.Finlize()
    if (slot < bmtVT->cVirtualSlots && (*bmtVT)[slot].Impl().GetMethodDesc() != g_pObjectFinalizerMD)
    {
        GetHalfBakedMethodTable()->SetHasFinalizer(); //這個地方就是設置m_dwFlags
        //此處省略一萬行
    }
}

2.調用GC.SuppressFinalize

設置當前類的對象頭

headerobj|BIT_SBLK_FINALIZER_RUN當我們調用GC.SuppressFinalize的時候,它會進行判斷m_dwFlags或上的enum_flag_HasFinalizer位是否為1,如果位0直接返回,如果為1,則設置對象頭。它的判斷邏輯如下

if (!obj->GetMethodTable ()->HasFinalizer())//HasFinalizer函數判斷m_dwFlags的enum_flag_HasFinalizer位
return;
GCHeapUtilities::GetGCHeap()->SetFinalizationRun(obj);//這里設置當前類的對象頭headerobj|BIT_SBLK_FINALIZER_RUN
BIT_SBLK_FINALIZER_RUN定義如下:
#define BIT_SBLK_FINALIZER_RUN   0x40000000

3.對象進行分配空間的時候

設置flags |= GC_ALLOC_FINALIZE一個對象需要進行空間的分配,當進行空間分配的時候,它會判斷當前函數是否包含了析構函數。如果包含了,則設置flags標志最后一位位1.然后在對象分配的時候,把它放入到析構隊列里面去。

if (pMT->HasFinalizer())//判斷當前類是否包含析構函數
    flags |= GC_ALLOC_FINALIZE;//如果包含則設置flags最后一位為1
GC_ALLOC_FINALIZE定義如下:
enum GC_ALLOC_FLAGS
{
    GC_ALLOC_NO_FLAGS           = 0,
    GC_ALLOC_FINALIZE           = 1,
    GC_ALLOC_CONTAINS_REF       = 2,
    GC_ALLOC_ALIGN8_BIAS        = 4,
    GC_ALLOC_ALIGN8             = 8,
    GC_ALLOC_ZEROING_OPTIONAL   = 16,
    GC_ALLOC_LARGE_OBJECT_HEAP  = 32,
    GC_ALLOC_PINNED_OBJECT_HEAP = 64,
    GC_ALLOC_USER_OLD_HEAP      = GC_ALLOC_LARGE_OBJECT_HEAP | GC_ALLOC_PINNED_OBJECT_HEAP,
};

當進行對象分配的時候,它會判斷falgs最后一位是否為1,如果為1,則把對象放入到析構隊列,不為1,則不放入。

CHECK_ALLOC_AND_POSSIBLY_REGISTER_FOR_FINALIZATION(newAlloc, size, flags & GC_ALLOC_FINALIZE); //flags & GC_ALLOC_FINALIZE判斷falgs最后一位是否為1.


#define CHECK_ALLOC_AND_POSSIBLY_REGISTER_FOR_FINALIZATION(_object, _size, _register) do {
    //這里的register就是flags & GC_ALLOC_FINALIZE的值,下面的邏輯如果對象為空直接返回,如果不為空則判斷flags & GC_ALLOC_FINALIZE是否等于1,如果為零直接返回,如果為1,則調用REGISTER_FOR_FINALIZATION,把對象放入析構隊列
    if ((_object) == NULL || ((_register) && !REGISTER_FOR_FINALIZATION(_object, _size))) 
    {
        STRESS_LOG_OOM_STACK(_size);
        return NULL;
    }

以上是析構函數,GC.SuppressFinalize,Dispose的最底層邏輯。當然這里還有很多技術問題需要解決。后面再看。

標記的作用

GC.SuppressFinalize問題來了,它的這些標記有什么用呢?這是一個非常繞的問題,分析下。首先的enum_flag_HasFinalizer標記表示當前類包含了析構函數,GC_ALLOC_FINALIZE標記表示當前的類對象需要填充到析構隊列里面去。

而BIT_SBLK_FINALIZER_RUN標記是最為重要的,它如果被標記了則表示從析構隊列里面溢出,不需要運行這個當前類的析構函數。

在GC的標記階段標記對象是否存活完成之后,它需要對對象的析構隊列進行掃描。如果析構隊列(SegQueue)里的對象被標記存活,且它的對象頭有

BIT_SBLK_FINALIZER_RUN標志,則表示此對象的析構隊列里的對象可以移出了,也就是不運行此對象的析構函數。

//這里的ScanForFinalization是在GCScanRoot之運行的,還有一個從析構函數里面取出
//對象運行析構函數則是GCHeap::GetNextFinalizableObject
CFinalize::ScanForFinalization (promote_func* pfn, int gen, BOOL mark_only_p,
                                gc_heap* hp)
{   
  //判斷對象頭是否標記了BIT_SBLK_FINALIZER_RUN
  if ((obj->GetHeader()->GetBits()) & BIT_SBLK_FINALIZER_RUN)
                    {
                        //如果標記了,則把這個對象移除到FreeList,也即是空閑的析構列表,不然存在于析構列表中
                        MoveItem (i, Seg, FreeList);
                        //然后清除掉此對象頭BIT_SBLK_FINALIZER_RUN標志
                        obj->GetHeader()->ClrBit (BIT_SBLK_FINALIZER_RUN);
                    }
}
再論CLR析構函數.net 6 析構函數的幾個特性CLR析構列表是如何添加析構函數類的
責任編輯:武曉燕 來源: 江湖評談
相關推薦

2023-10-11 14:18:40

C#.Net析構

2021-12-11 19:02:03

函數C++對象

2009-08-14 17:24:28

C#構造函數和析構函數

2025-02-18 00:08:00

代碼C++RAII

2009-09-03 13:14:55

C#構造函數C#析構函數

2010-07-20 09:52:27

Perl構造函數

2010-02-04 16:39:26

C++析構函數

2010-01-18 15:53:27

C++析構函數

2009-12-04 17:16:41

PHP析構函數

2010-07-16 17:12:58

Perl析構函數

2011-07-15 01:29:39

C++析構函數

2009-07-30 15:24:13

C#析構函數C#構造函數

2024-12-19 14:42:15

C++內存泄漏內存管理

2010-02-05 13:35:19

C++虛析構函數

2009-11-24 16:18:14

PHP5析構函數

2009-09-02 10:49:46

C#調用析構方法

2009-10-15 17:50:48

VB.NET調用API

2015-12-15 09:58:19

golang環境配置建議

2010-09-07 13:40:02

DIV標簽

2010-03-29 09:11:02

Python引用計數
點贊
收藏

51CTO技術棧公眾號

综合久久五月天| 久久久噜噜噜www成人网| 国产美女精品视频免费播放软件 | 久久久久久国产精品mv| 精品日韩在线| 欧美亚洲国产成人精品| jizz性欧美2| 久久久91精品国产| 97精品国产99久久久久久免费| 欧美一级一区二区| 日本韩国在线视频爽| 91黄色激情网站| 91社区在线| 欧美日韩黄色一区二区| 91se在线| 日韩精品中文字幕一区二区三区| caoporn97在线视频| 欧美电影精品一区二区| www.九色在线| 中文字幕在线视频日韩| 亚洲伦理网站| 97在线视频精品| 精品国产中文字幕第一页| 国产精品久久久久久久久影视| 国产亚洲一区二区三区不卡| 国产精品一区电影| 国语对白精品一区二区| 欧美凹凸一区二区三区视频 | 91色在线porny| 国产h视频在线播放| av中文字幕不卡| 国产精品天天av精麻传媒| 久久久一区二区三区捆绑**| 国产精品wwwww| 亚洲美女视频在线| 久久精品国产亚洲a∨麻豆| 欧美美女黄视频| 免费看av不卡| 96精品视频在线| 色一区二区三区四区| 国产精品一 二 三| 另类小说一区二区三区| 成人小视频在线观看免费| www久久精品| 香港三级经典全部种子下载| 欧美日韩美女一区二区| 日韩精品三区| 国产成人精品免高潮在线观看| 欧美日韩1区2区3区| 伊人色综合久久天天五月婷| 久久久久久夜精品精品免费| 一区二区三区四区在线免费视频| 日韩三级精品电影久久久| 成人在线视频观看| 国产精品久久久久91| 性8sex亚洲区入口| 日日摸天天爽天天爽视频| 亚洲一区二区三区小说| 国产在线69| 欧美丰满片xxx777| 亚洲夜间福利| 无码日韩人妻精品久久蜜桃| 在线欧美日韩国产| 成人精品高清在线视频| 国产精品视频中文字幕91| 丝袜美腿亚洲一区二区图片| 无码人妻丰满熟妇区五十路百度| 欧美丝袜一区二区| 日韩在线观看不卡| 国产自摸综合网| 成人性生交大片免费看视频在线| 男人本色网站| 日韩成人av在线播放| 精品72久久久久中文字幕| 日本午夜精品一区二区三区| 国产精品免费av| jizzjizz中国精品麻豆| 国产成人综合精品在线| 国产一区二区三区香蕉 | 国产欧美日韩卡一| 欧美寡妇性猛交xxx免费| 日韩av免费在线观看| 国产一区二区福利| 一二三区在线| 久久影院中文字幕| 久久久久99| 在线免费观看你懂的| 亚洲深夜福利视频| 亚洲成人原创| 97秋霞电影网| 色系列之999| 日本欧美大码aⅴ在线播放| 理论片在线观看理伦片| 久久精品夜夜夜夜夜久久| 久久久噜噜噜| 一级片在线免费看| 欧美黑人性猛交| 国模少妇一区二区三区| 国产尤物视频在线| 国产精品成人久久久久| 99视频国产精品| 漫画在线观看av| ts人妖另类在线| 一区二区三区在线影院| 国产一区二区三区免费观看在线| 欧美一区二区三区在线播放| 欧美视频在线观看免费| 日韩精品福利一区二区三区| 水蜜桃在线免费观看| 7777精品伊人久久久大香线蕉经典版下载| 欧美美女在线| 亚洲综合欧美激情| zzjj国产精品一区二区| 极品少妇一区二区| 在线三级电影| 爱情岛论坛亚洲入口| 天天操天天干天天综合网| aaa国产精品| 日韩黄色片视频| 日韩在线资源网| 国产激情一区二区三区桃花岛亚洲 | 亚洲免费人成在线视频观看| 中文亚洲字幕| 你懂的在线看| 国产精品视频色| 亚洲视频香蕉人妖| 久久精品凹凸全集| 第四色婷婷基地| 高清一区二区三区日本久| 久久午夜羞羞影院免费观看| 久久三级毛片| 国产一二三区在线播放| 精品亚洲精品福利线在观看| 久久香蕉精品| 成人a在线视频免费观看| 蜜桃久久精品乱码一区二区| 在线观看日韩av先锋影音电影院| 91精品国产91久久久久久密臀 | 国产午夜精品久久久久久免费视 | 日韩免费观看高清完整版在线观看| 好看不卡的中文字幕| 国产在线自天天| 久久99精品久久久久久久久久| 欧美日韩情趣电影| 日韩精品免费视频人成| 三级成人黄色影院| 青青青在线播放| 国产精国产精品| 91成人网在线| 久久超碰97人人做人人爱| 成人做爰视频www网站小优视频| 久久久久久久久久网| 久久福利视频导航| 一区二区三区四区在线免费观看| 91综合久久| gogo在线高清视频| 国产精彩视频一区二区| 久久久久久久久久国产精品| 亚洲综合色视频| 亚洲国产激情| a级片在线免费| 成年人免费在线播放| 国产成人精品网站| 欧美日韩视频免费播放| 国产精品亚洲综合久久| 91p九色成人| 久久.com| 人偷久久久久久久偷女厕| 综合国产在线视频| 亚洲一区中文日韩| 日韩高清一级片| 亚洲国产aⅴ精品一区二区| 屁屁影院在线观看| 日韩激情久久| 欧美成人免费在线观看| 色综合天天综合色综合av | 青青国产精品| 污污免费网站| 亚洲精品中文字幕在线 | 日韩精品第二页| 91短视频在线| 亚洲 日韩 国产第一区| 欧美成人精品影院| 日本乱人伦aⅴ精品| 四虎影视精品成人| 国产九色精品| 久久精品国产一区二区三区| 欧美日韩一区二区免费视频| 国产伦精品一区二区三区免费迷| 看全色黄大色大片免费久久久| 免费在线黄色电影| 国产h视频在线播放| 91牛牛免费视频| 亚洲小视频在线| 精品久久久久久久久国产字幕 | 日本高清中文字幕| 精品乱码一区| 久久99精品久久久久久秒播放器 | 国产视频视频一区| 99久久er热在这里只有精品15|