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

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

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

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

?? 一、什么是 GC?

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

它的作用是:

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

你不需要像 C/C++ 那樣手動(dòng) deletefree,C# 的 GC 會(huì)幫你搞定!

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

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

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

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

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

GC 不是實(shí)時(shí)運(yùn)行的,而是在滿足以下條件之一時(shí)自動(dòng)觸發(fā)

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

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

??? 四、GC 如何判斷一個(gè)對(duì)象是“垃圾”?

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

什么是“根(Root)”?

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

示例:

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

→ 此時(shí) Person 對(duì)象不可達(dá),下次 GC 時(shí)會(huì)被回收。

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

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

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

為什么分代?

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

回收過(guò)程簡(jiǎn)述:

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

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

?? 六、如何查看對(duì)象在哪一代?

可以使用 GC.GetGeneration(object)

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

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

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

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

解決方案:實(shí)現(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)— 最后的保險(xiǎn)
    {
        Dispose();
    }
}

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

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

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

可能的問(wèn)題:

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

優(yōu)化建議:

場(chǎng)景建議
頻繁創(chuàng)建小對(duì)象?? 重用對(duì)象(對(duì)象池 ObjectPool<T>)
大數(shù)組/緩沖區(qū)?? 使用 ArrayPool<T>.Shared
長(zhǎng)時(shí)間持有對(duì)象?? 避免無(wú)意中延長(zhǎng)對(duì)象生命周期(如事件訂閱未取消)
高性能場(chǎng)景?? 減少分配(如用 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 手動(dòng)內(nèi)存管理(C++)

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

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

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

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

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

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

相關(guān)文章

最新評(píng)論

谢通门县| 新安县| 林西县| 高阳县| 大荔县| 大丰市| 牙克石市| 华宁县| 正安县| 古蔺县| 五大连池市| 汤原县| 三都| 临邑县| 张北县| 土默特左旗| 饶阳县| 绍兴县| 正定县| 广灵县| 宜州市| 普兰店市| 平乡县| 九江县| 东阿县| 甘洛县| 双鸭山市| 阿拉尔市| 珲春市| 抚松县| 邹城市| 锦州市| 榆社县| 噶尔县| 百色市| 荣成市| 梁山县| 桐庐县| 突泉县| 那曲县| 河源市|