成人免费xxxxx在线视频软件_久久精品久久久_亚洲国产精品久久久_天天色天天色_亚洲人成一区_欧美一级欧美三级在线观看

C#.Net析構知識引申(CLR級的剖析)

開發 前端
SetEvent通知線程進行工作,那么析構線程呢,則是CLR在某個時間段通知其進行工作。具體的表現為,注冊析構函數,掃描析構函數,這兩步完成之后,就會通過SetEvent來通知析構線程,你可以進行工作了。

一.前言

析構函數是一個特殊的函數,它有自己的線程,有自己的實現方式。在CLR里面相當于一個小型的自我運轉系統(有的書本把這個稱之為終結器)。來看下一些概念以及一些運行模型。

二.概述

析構函數有一堆的概念
1.析構對象列表(也就是存放了包含析構函數的對象),它是最原始的。也就是當進行對象實例化分配的時候,會判斷此對象是否包含了析構函數,如果包含了,則把此對象添加到析構對象列表。

flags & GC_ALLOC_FINALIZE

2.析構空閑列表(FreeList==7,也即是不允許被調用的析構函數所在的對象,這些對象存放在這個列表),它是C#里面一個著名的: GC.SuppressFinalize()來啟用,以不允許CLR調用虛構函數。前提是首先這個對象里面包含了析構函數,然后才可以設置相應的標志位用以讓CLR不執行此對象的析構函數。并且GC運行的時候也會需要這個對象沒有存活才可以放入到析構空閑列表。

if (!obj->GetMethodTable ()->HasFinalizer())
    return;//這里如果對象不包含析構函數,則直接返回,即使啟用了GC.SuppressFinalize也毫無作用。
GCHeapUtilities::GetGCHeap()->SetFinalizationRun(obj);//這里給ObjectHeader設置BIT_SBLK_FINALIZER_RUN標志,當GC進行掃描的時候,發現了這個標志,并且此對象沒有被標記存活,那么此對象就放入到析構空閑列表

關于GC運行的時候也會需要判斷這個對象沒有存活才可以放入到析構空閑列表。

if (!g_theGCHeap->IsPromoted (obj))//GC運想需要判斷此對象是否存活,不存活才可以進行下一步
 {
  //然后會判斷是否包含了GC.SuppressFinalize設置的標志,如果包含,則表示此對象的析構函數不運行運行,把這個對象放入到空閑析構隊列
  if ((obj->GetHeader()->GetBits()) & BIT_SBLK_FINALIZER_RUN)
  {
    MoveItem (i, Seg, FreeList);//把對象移動到析構空閑隊列
    obj->GetHeader()->ClrBit (BIT_SBLK_FINALIZER_RUN);//清除GC.SuppressFinalize設置的標記
}

3.關鍵析構函數列表堆(CriticalFinalizerListSeg==5這個隊列目前的情況不是太明了,尚未弄清它是做什么的,先擱置)

4.析構列表堆(FinalizerListSeg==6,它存放的是需要被析構線程調用的析構函數所在的對象)

三.原理

了解了以上概念之后,我們來看下它這些隊列的內存模型。首先要明確的一點是這些列表共用一個數組。CLR只是對這個數組進行騷操作,用以區分析構對對象列表,FreeList,CriticalFinalizerListSeg,FinalizerListSeg等四個隊列。

圖片圖片


圖標里面缺少一個析構對象列表,那是因為析構對象列表頁是跟它們共用一個地址,也即是m_FillPointers數組值0x100地址。

它們如何操作和分配呢?

1.當對象進行實例化的時候,把包含析構函數的對象添加到析構對象列.

2.當析構函數列表添加完畢之后,在進行GC垃圾回收的時候。在標記對象的動作里面也即是mark_phase里,會對析構對象列表進行掃描。掃描的時候會進行以下動作。
首先,會獲取當前GC堆代的起始地址。從這個起始地址開始遍歷循環到第三代結尾地址。在這個大循環前提下,里面有個小循環。小循環的作用是找出循環堆里面的析構對象列表。也即是圖示的m_FillPointers數組的值。當找到析構對象列表,循環這個析構對象列表里面的對象,判斷它是否存活,如果存活則不進行處理。如果不存活,則分情況。分別會移動到

FreeList,CriticalFinalizerListSeg,FinalizerListSeg等三個隊列。
FreeList也即是析構空閑列表,它里面包含的對象的析構函數永遠不會被調用。FinalizerListSeg里面包含了被調用的析構函數對象。CriticalFinalizerListSeg目的不明確,目前不清楚干什么。

3.當掃描完畢完畢析構對象列表之后,就會啟動析構線程。析構線程會調用

FinalizerListSe列表和CriticalFinalizerListSe分別運行里面的析構函數。過程是:這個線程會判斷索引6也即是FinalizerListSe和索引5是否相等,如果不相等。則表示有析構函數需要調用,把這個對象取出來,然后調用里面的析構函數。然后會判斷索引5也即是

CriticalFinalizerListSe,跟FinalizerListSe同樣的方式.

4.RegisterForFinalization(注冊析構函數,也即是把有析構函數的對象放到析構列表)
ScanForFinalization(掃描析構列表,也即是區分關鍵析構列表堆,析構空閑列表等)
GetNextFinalizableObject(調用析構函數)

四.析構線程

析構線程用的是windows事件內核對象來操控的,這里舉一個簡單的例子

#include <stdio.h>
#include <windows.h>
#include <process.h>


HANDLE g_hEvent;
UINT __stdcall ChildFunc(LPVOID);


int main(int argc, char* argv[])
{
  HANDLE hChildThread;
  UINT uId;


  // 創建一個自動重置的(auto-reset events),未受信的(nonsignaled)事件內核對象
  g_hEvent = ::CreateEvent(NULL, FALSE, FALSE, NULL);


  hChildThread = (HANDLE)::_beginthreadex(NULL, 0, ChildFunc, NULL, 0, &uId);


  // 通知子線程開始工作
  printf("Please input a char to tell the Child Thread to work: \n");
  getchar();
  ::SetEvent(g_hEvent);


  // 等待子線程完成工作,釋放資源
  ::WaitForSingleObject(hChildThread, INFINITE);
  printf("All the work has been finished. \n");
  ::CloseHandle(hChildThread);
  ::CloseHandle(g_hEvent);
  return 0;
}


UINT __stdcall ChildFunc(LPVOID)
{
  ::WaitForSingleObject(g_hEvent, INFINITE);
  printf("  Child thread is working...... \n");
  ::Sleep(5*1000); // 暫停5秒,模擬真正的工作
  return 0;
}

SetEvent通知線程進行工作,那么析構線程呢,則是CLR在某個時間段通知其進行工作。具體的表現為,注冊析構函數,掃描析構函數,這兩步完成之后,就會通過SetEvent來通知析構線程,你可以進行工作了。此時析構線程就會從析構對象列表里面取出CriticalFinalizerListSe和FinalizerListSe來調用析構函數。

責任編輯:武曉燕 來源: 江湖評談
相關推薦

2023-10-09 09:02:50

.Net析構函數分配

2009-09-18 11:29:23

.NET CLR

2011-06-17 15:55:19

ArrayListC#

2009-08-25 13:53:20

C#.NET rege

2009-08-26 14:23:14

C#.Net Fram

2009-08-13 10:35:55

C#.NET操作XML

2009-08-24 16:19:54

C#.NET綁定Off

2009-08-26 10:09:22

C#編碼規范

2009-09-02 10:49:46

C#調用析構方法

2025-02-18 00:08:00

代碼C++RAII

2011-07-15 01:29:39

C++析構函數

2009-09-11 11:30:53

Net60C#.NET

2009-08-24 16:30:43

C#.NET綁定Off

2009-08-19 15:44:09

ObjectARX .

2010-02-04 16:39:26

C++析構函數

2009-08-14 17:24:28

C#構造函數和析構函數

2010-01-18 15:53:27

C++析構函數

2009-04-02 15:21:43

c#IDisposeFinalize

2009-08-31 14:45:15

C#.NET多線程應用

2011-06-15 09:47:14

C++
點贊
收藏

51CTO技術棧公眾號

主站蜘蛛池模板: аⅴ资源新版在线天堂 | 久干网 | 欧美成人影院 | 久久精品国产一区 | 午夜久久久久久久久久一区二区 | 97精品视频在线观看 | 97人人草 | 亚洲欧美综合 | 国产乱码精品一区二区三区五月婷 | 成人特级毛片 | 中文字幕在线不卡播放 | 欧美中文在线 | 亚洲成人福利在线观看 | 美女视频黄色片 | 欧美亚洲另类丝袜综合网动图 | 国产精品视频久久久久 | 欧美日韩国产精品一区二区 | 国产一区成人 | 91 在线| 日韩中文字幕第一页 | 欧美日韩电影一区二区 | 免费一级大片 | 日本久久精品视频 | www.精品国产| 成人亚洲| 亚洲精品久久久久久一区二区 | 久久精品a级毛片 | 国内自拍视频在线观看 | 一区二区高清 | 成人性生交大片免费看中文带字幕 | 日韩电影免费观看中文字幕 | 国产一区免费 | 亚洲福利在线视频 | 日韩一区二区在线看 | 国产精品成人在线播放 | 91精品国产91久久久久久吃药 | 精品欧美乱码久久久久久1区2区 | 国产精品久久久久久婷婷天堂 | www.天天操| 日本在线中文 | 欧美视频在线播放 |