最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

C# GC回收的方法實現(xiàn)

 更新時間:2025年11月27日 10:57:26   作者:她說彩禮65萬  
本文主要介紹了C# GC回收的方法實現(xiàn),文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧

介紹 C# 中的 垃圾回收(Garbage Collection, GC) 機制。

?? 一、什么是 GC?

GC(Garbage Collector,垃圾回收器) 是 .NET 運行時(CLR)自動管理內(nèi)存的核心組件。

它的作用是:

自動找出不再被使用的對象(“垃圾”),并釋放它們占用的內(nèi)存,防止內(nèi)存泄漏。

你不需要像 C/C++ 那樣手動 deletefree,C# 的 GC 會幫你搞定!

?? 二、GC 管理的是哪部分內(nèi)存?

在 C# 中,內(nèi)存主要分為兩塊:

內(nèi)存區(qū)域存放內(nèi)容是否由 GC 管理
托管堆(Managed Heap)引用類型對象(如 class 實例)? 是
棧(Stack)值類型(如 int, struct)、方法局部變量、引用類型的引用(指針)? 否(隨方法結(jié)束自動釋放)

?? 注意:string、數(shù)組、自定義 class 都分配在托管堆上,由 GC 負責回收。

?? 三、GC 什么時候觸發(fā)?

GC 不是實時運行的,而是在滿足以下條件之一時自動觸發(fā)

  1. 托管堆內(nèi)存不足(分配新對象時發(fā)現(xiàn)空間不夠)
  2. 系統(tǒng)內(nèi)存壓力大(Windows 通知 .NET 內(nèi)存緊張)
  3. 手動調(diào)用 GC.Collect()(不推薦!除非特殊場景)

?? 開發(fā)者通常無法精確控制 GC 何時發(fā)生,這是設計上的有意為之——讓開發(fā)者專注業(yè)務邏輯。

??? 四、GC 如何判斷一個對象是“垃圾”?

核心原則:如果一個對象無法從“根(Root)”訪問到,它就是垃圾。

什么是“根(Root)”?

  • 全局/靜態(tài)變量
  • 方法中的局部變量(包括參數(shù))
  • CPU 寄存器中的引用
  • 本地方法(Native code)持有的引用

示例:

void MyMethod()
{
    var person = new Person(); // person 是局部變量 → 根
    person.Name = "Alice";
} // 方法結(jié)束,person 超出作用域 → 不再是根

→ 此時 Person 對象不可達,下次 GC 時會被回收。

?? 五、GC 的核心機制:分代回收(Generational GC)

.NET 的 GC 采用 “分代回收” 策略,把對象按“年齡”分成三代:

代(Generation)特點回收頻率
Gen 0新創(chuàng)建的對象?? 最頻繁(毫秒級)
Gen 1活過一次 Gen 0 回收的對象中等
Gen 2老對象(活過 Gen 1)?? 最少(可能幾秒甚至幾分鐘一次)

為什么分代?

經(jīng)驗規(guī)律:大多數(shù)對象“朝生暮死”(比如臨時變量)。
所以優(yōu)先快速回收 Gen 0,避免全堆掃描,提升性能。

回收過程簡述:

  1. GC 暫停所有線程(“Stop-The-World”)
  2. 從“根”出發(fā),標記所有可達對象
  3. 清除未標記對象(垃圾)
  4. 壓縮內(nèi)存:把存活對象往堆的一端移動,消除碎片
  5. 晉升:Gen 0 存活對象 → Gen 1;Gen 1 存活 → Gen 2

?? Gen 2 回收也叫 Full GC,開銷最大,應盡量避免頻繁發(fā)生。

?? 六、如何查看對象在哪一代?

可以使用 GC.GetGeneration(object)

var obj = new object();
Console.WriteLine(GC.GetGeneration(obj)); // 輸出 0

GC.Collect(); // 強制回收 Gen 0
Console.WriteLine(GC.GetGeneration(obj)); // 如果 obj 還被引用,輸出 1

??? 七、特殊對象:需要“清理”的資源

GC 只負責內(nèi)存回收,但有些對象持有非托管資源(如文件句柄、數(shù)據(jù)庫連接、網(wǎng)絡 socket),這些資源不會自動釋放!

解決方案:實現(xiàn)IDisposable+Dispose模式

public class MyFile : IDisposable
{
    private FileStream _file;

    public MyFile(string path)
    {
        _file = File.OpenRead(path);
    }

    public void Dispose()
    {
        _file?.Dispose(); // 立即釋放非托管資源
        GC.SuppressFinalize(this); // 告訴 GC:不用調(diào)用析構(gòu)函數(shù)了
    }

    ~MyFile() // 析構(gòu)函數(shù)(Finalizer)— 最后的保險
    {
        Dispose();
    }
}

// 使用方式(推薦 using)
using (var file = new MyFile("data.txt"))
{
    // 使用文件
} // 自動調(diào)用 Dispose()

? 最佳實踐:對持有非托管資源的類,務必實現(xiàn) IDisposable,并用 using 語句確保及時釋放。

?? 八、GC 對性能的影響 & 優(yōu)化建議

可能的問題:

  • Stop-The-World:GC 期間所有線程暫停,可能導致 UI 卡頓
  • 頻繁分配/回收:大量臨時對象 → 頻繁 Gen 0 GC → CPU 浪費
  • 大對象堆(LOH):≥85,000 字節(jié)的對象分配在 LOH,不會壓縮,易產(chǎn)生內(nèi)存碎片

優(yōu)化建議:

場景建議
頻繁創(chuàng)建小對象?? 重用對象(對象池 ObjectPool<T>)
大數(shù)組/緩沖區(qū)?? 使用 ArrayPool<T>.Shared
長時間持有對象?? 避免無意中延長對象生命周期(如事件訂閱未取消)
高性能場景?? 減少分配(如用 Span<T>、stackalloc)
監(jiān)控 GC?? 使用 PerfView、dotMemory 或 GC.CollectionCount
// 查看各代 GC 次數(shù)
Console.WriteLine($"Gen 0: {GC.CollectionCount(0)}");
Console.WriteLine($"Gen 1: {GC.CollectionCount(1)}");
Console.WriteLine($"Gen 2: {GC.CollectionCount(2)}");

?? 九、GC vs 手動內(nèi)存管理(C++)

特性C# GCC++ 手動管理
內(nèi)存安全? 不會野指針、重復釋放? 容易出錯
開發(fā)效率? 高? 低
性能可控性? 較低(GC 不可預測)? 高
內(nèi)存碎片? GC 會壓縮堆? 需手動管理

?? C# 的設計理念:用少量性能代價,換取極高的開發(fā)安全性和效率

? 總結(jié):關(guān)鍵要點

  1. GC 自動回收托管堆上的無用對象,開發(fā)者無需手動釋放。
  2. 分代回收(Gen 0/1/2) 是核心優(yōu)化策略,基于“多數(shù)對象短命”假設。
  3. GC 不處理非托管資源 → 必須用 IDisposable + using。
  4. 避免頻繁分配臨時對象,尤其在循環(huán)或高頻方法中。
  5. 不要隨意調(diào)用 GC.Collect() —— 通常適得其反。
  6. 大對象(≥85KB)進入 LOH,不壓縮,需特別注意。

如果你正在開發(fā)高性能應用(如游戲、實時系統(tǒng)),理解 GC 行為至關(guān)重要;如果是普通業(yè)務系統(tǒng),只需記住:少 new 臨時對象,及時 Dispose 資源,就能避開 90% 的問題。

到此這篇關(guān)于C# GC回收的方法實現(xiàn)的文章就介紹到這了,更多相關(guān)C# GC回收內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論

镇巴县| 靖西县| 台中县| 景宁| 萨嘎县| 鄢陵县| 延长县| 五寨县| 桦南县| 蒲江县| 赤峰市| 阜康市| 阜康市| 娄烦县| 孟连| 乐亭县| 巩义市| 池州市| 尤溪县| 大田县| 花莲市| 三原县| 应城市| 永年县| 织金县| 滦平县| 丰原市| 新巴尔虎左旗| 牡丹江市| 伊吾县| 河东区| 张北县| 瑞昌市| 淮安市| 万山特区| 石景山区| 固阳县| 盈江县| 郯城县| 武安市| 聊城市|