【C#】詳解C#中的內存管理機制

文章目錄

  • 前言
  • 一、C#內存管理的基本機制
    • (1)托管堆(Managed Heap)
    • (2)垃圾回收(Garbage Collection)
    • (3)棧內存
  • 二、 開發者需要主動管理的場景
    • (1)非托管資源釋放
    • (2)大對象和內存優化
    • (3)循環引用與內存泄漏
  • 三、手動干預GC的罕見場景
    • (1)強制觸發GC
    • (2)弱引用(WeakReference)
  • 四、與非托管代碼交互
  • 五、總結


前言

在C#中,內存管理主要通過 垃圾回收(Garbage Collection, GC) 機制自動完成,但開發者仍需在特定場景下關注資源釋放和性能優化。以下是詳細解析:

一、C#內存管理的基本機制

(1)托管堆(Managed Heap)

  • C#中的對象(引用類型)分配在托管堆上,由 CLR(Common Language Runtime) 自動管理。

  • 無需手動釋放內存:垃圾回收器(GC)會周期性掃描托管堆,自動回收不再被引用的對象占用的內存。

(2)垃圾回收(Garbage Collection)

  • 分代回收:GC將對象分為三代(0/1/2代),新對象分配在0代。0代內存滿時觸發回收,存活對象晉升到下一代。

  • 非確定性回收:GC觸發時機由CLR控制,開發者無法精確控制。

(3)棧內存

  • 值類型(如int、struct)分配在棧上,生命周期由作用域控制(方法結束時自動釋放)。

二、 開發者需要主動管理的場景

雖然C#內存管理是自動的,但在以下場景仍需開發者介入:

(1)非托管資源釋放

  • 問題:文件句柄、數據庫連接、網絡套接字等非托管資源(非CLR管理)需手動釋放。

  • 解決方案:

    • 實現IDisposable接口,在Dispose()方法中釋放資源。

    • 使用using語句確保資源及時釋放:

    using (var file = File.Open("test.txt", FileMode.Open))
    {// 操作文件
    } // 自動調用file.Dispose()
    

(2)大對象和內存優化

  • 大對象堆(Large Object Heap, LOH):對象大小超過85KB時分配在LOH,LOH不會壓縮,可能導致內存碎片。

  • 優化策略:

    • 避免頻繁分配大對象(如緩存復用)。

    • 使用ArrayPool或對象池減少內存分配壓力。

(3)循環引用與內存泄漏

  • 問題:若對象之間存在循環引用(如事件綁定未取消),即使對象不再使用,GC也可能無法回收。

  • 示例:

    public class Publisher
    {public event EventHandler Event;
    }public class Subscriber
    {public Subscriber(Publisher pub){pub.Event += HandleEvent; // 訂閱事件}private void HandleEvent(object sender, EventArgs e) { }
    }// 使用后未取消訂閱,Subscriber和Publisher會互相引用,無法被GC回收!
    
  • 解決:及時取消事件訂閱(pub.Event -= HandleEvent)。

三、手動干預GC的罕見場景

(1)強制觸發GC

  • 通過GC.Collect()手動觸發回收,但通常不建議使用(影響性能)。

  • 適用場景:性能測試或內存泄漏調試。

(2)弱引用(WeakReference)

  • 允許對象被GC回收,同時保留訪問能力:

    var weakRef = new WeakReference(new object());
    if (weakRef.IsAlive)
    {var obj = weakRef.Target; // 獲取對象(可能已被回收)
    }
    

四、與非托管代碼交互

  • 調用C/C++庫或系統API時,需通過unsafe代碼或Marshal類手動分配/釋放內存:

    IntPtr buffer = Marshal.AllocHGlobal(1024); // 分配非托管內存
    // 使用buffer...
    Marshal.FreeHGlobal(buffer); // 手動釋放
    

五、總結

  • 自動管理:C#通過GC自動回收托管堆內存,開發者無需手動釋放。

  • 需關注的場景:

    • 非托管資源(文件、網絡等)需通過IDisposable釋放。

    • 避免內存泄漏(如循環引用、事件未取消)。

    • 優化大對象和頻繁內存分配。

  • 工具輔助:使用內存分析工具(如Visual Studio Diagnostic Tools、JetBrains dotMemory)檢測內存問題。

  • 代碼示例:實現IDisposable

public class ResourceHolder : IDisposable
{private FileStream _file; // 非托管資源示例public ResourceHolder(string path){_file = File.Open(path, FileMode.Open);}public void Dispose(){_file?.Dispose(); // 釋放資源GC.SuppressFinalize(this); // 避免重復回收}// 析構函數(備用,防止忘記調用Dispose)~ResourceHolder(){Dispose();}
}// 使用示例
using (var holder = new ResourceHolder("test.txt"))
{// 使用資源
}

掌握這些原則,可以更高效地利用C#的自動內存管理,同時避免常見陷阱。

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/72876.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/72876.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/72876.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

ROS云課基礎題庫-01C++案例-甜甜圈

效率是核心,但效率高的教程會忽略掉非常多的細節。 解決問題的思路和細節對于一個問題的有效求解至關重要。 資料 云課五分鐘-02第一個代碼復現-終端甜甜圈C-CSDN博客 從云課五分鐘到五秒鐘焦慮的甜甜圈向前沖-CSDN博客 說明 復現重要性沒有那么大,…

C/S架構與B/S架構

一、定義與核心區別 C/S架構(Client/Server,客戶端/服務器) 客戶端需安裝專用軟件(如QQ、企業ERP系統),直接與服務器通信。服務器端通常包括數據庫和業務邏輯處理1。特點:客戶端承擔部分計算任務…

【匯編語言】單片機程序執行過程

一、任務需求 指示燈LED4閃爍,亮0.5秒,滅0.5秒,無限循環 二、針對硬件的編程 1、確定原理圖2、確定硬件的物理關系 三、設計步驟 1.用自己的語言描述工作流程 1.1指示燈LED4亮1.2延時0.5秒1.3指示燈LED4滅1.4延時0.5秒1.5跳轉到1.1步 …

openharmony 富對富 WiFi投屏設計

castengine_wifi_display部件別名Sharing,媒體分享之意。擁有流媒體協議接入、媒體預覽、媒體轉分發能力,受投播管理服務管理和調用,是音視頻投播子系統重要的流媒體能力部件。提供一套簡單的Native C的接口,主要業務是Miracast投…

Android項目優化同步速度

最近項目需要使用ffmpeg,需要gradle配置引入ffmpeg庫,發現原來通過google官方的代碼倉,下載太慢了,每秒KB級別的速度。(之前下gradle/gradle plugin都不至于這么慢),于是想到配置國內鏡像源來提…

Git 如何配置多個遠程倉庫和免密登錄?

自我簡介:4年導游,10年程序員,最近6年一直深耕低代碼領域,分享低代碼和AI領域見解。 通用后臺管理系統 代號:虎鯨 緣由 每次開發后臺界面都會有很多相同模塊,嘗試抽離出公共模塊作為快速開發的基座。 目標…

JVM組成面試題及原理

Java Virtual Machine(JVM)是Java程序的運行環境(java二進制字節碼的運行環境) 好處: 一次編寫,到處運行自動內存管理,垃圾回收機制 JVM由哪些部分組成,運行流程是什么?…

江科大51單片機筆記【11】AT24C02數據存儲秒表

一、數據存儲 先把需要的模塊導入做個測試 //main.c#include <REGX52.H> #include " LCD1602.h" #include " Key.h"void main() {LCD_Init();LCD_ShowString(1,1,"Hello");while(1){}} 代碼思路 分成兩塊寫&#xff0c;一塊寫I2C.c&am…

Hadoop的運行模式

Hadoop的運行模式 1、本地運行模式2、偽分布式運行模式3、完全分布式運行模式4、區別與總結 Hadoop有三種可以運行的模式&#xff1a;本地運行模式、偽分布式運行模式和完全分布式運行模式 1、本地運行模式 本地運行模式無需任何守護進程&#xff0c;單機運行&#xff0c;所有…

2.裝飾器模式

概述 裝飾器模式&#xff1a;在原有結構&#xff0c;動態地為對象添加職責&#xff0c;它是一種靈活的擴展功能方式。 業務場景&#xff1a;創建訂單 假設你正在開發一個電商系統&#xff0c;用戶在創建訂單時可以選擇不同的服務&#xff08;如折扣、配送、禮品包裝等&#…

C++11新特性 10.初始化列表、initializer_list

目錄 一.初始化列表 使用示例 二.initializer_list 1.基本概念 2.使用示例 一.初始化列表 C11提供的統一初始化方式&#xff0c;實現直接對數據初始化 使用示例 /* 初始化列表 */ #include <iostream> using namespace std; class Person { public:Person(string…

Vue 的 render 函數如何與 JSX 結合使用

在 Vue.js 中&#xff0c;render 函數提供了一種更底層的方式來創建虛擬 DOM 節點&#xff0c;而 JSX 則是一種 JavaScript 的語法擴展&#xff0c;允許開發者在 JavaScript 代碼中直接編寫類似 HTML 的結構。結合使用 render 函數和 JSX 可以帶來更高的靈活性和編程能力&#…

基于DeepSeek的智慧醫藥系統(源碼+部署教程)

運行環境 智慧醫藥系統運行環境如下&#xff1a; 前端&#xff1a; HTMLCSS后端&#xff1a;Java AIGCDeepseekIDE工具&#xff1a;IDEA技術棧&#xff1a;Springboot HTMLCSS MySQL 主要角色 智慧醫藥系統主要分為兩個角色。 游客 尚未進行注冊和登錄。具備登錄注冊、…

南開提出1Prompt1Story,無需訓練,可通過單個連接提示實現一致的文本到圖像生成。

&#xff08;1Prompt1Story&#xff09;是一種無訓練的文本到圖像生成方法&#xff0c;通過整合多個提示為一個長句子&#xff0c;并結合奇異值重加權&#xff08;SVR&#xff09;和身份保持交叉注意力&#xff08;IPCA&#xff09;技術&#xff0c;解決了生成圖像中身份不一致…

BLUEM2引擎源碼2025最新版

BLUE 引擎解析&#xff1a;傳奇私服圈中的熱門引擎 一、BLUE 引擎簡介 BLUE 引擎是傳奇私服圈子中較為知名的一款游戲引擎&#xff0c;它在傳統的傳奇引擎基礎上進行了優化和擴展&#xff0c;使得私服開發者可以更加方便地搭建和管理服務器。相比于早期的 GEE、LEG、Hero 等引…

第53天:Web攻防-SQL注入數據庫類型用戶權限架構分層符號干擾利用過程發現思路

#知識點&#xff1a;(本節課了解即可&#xff09; 1、Web攻防-SQL注入-產生原理&應用因素 2、Web攻防-SQL注入-各類數據庫類型利用 一、數據庫知識&#xff1a; 1、數據庫名&#xff0c;表名&#xff0c;列名&#xff0c;數據 2、自帶數據庫&#xff0c;數據庫用戶及權限 3…

【玩轉MySQL數據字典】MySQL數據字典與常用操作指令

MySQL數據字典簡介與常用操作指令 一、數據字典簡介 數據字典是MySQL 5.7中用于存儲數據庫對象元數據的系統表。在MySQL的早期版本中&#xff0c;元數據存儲在.frm文件及其他文件里。這種存儲方式存在諸多弊端&#xff0c;例如元數據不一致問題&#xff0c;不同文件間元數據的…

如何有效判斷與排查Java GC問題

目錄 一、GC的重要性與對性能的影響 &#xff08;一&#xff09;GC對性能的影響簡要分析 1.GC暫停與應用停頓 2.GC吞吐量與資源利用率 3.GC對內存管理的作用&#xff1a;資源回收 4.GC策略與優化的選擇 &#xff08;二&#xff09;GC的雙刃劍 二、GC性能評價標準 &…

el-table(elementui)表格合計行使用以及滾動條默認樣式修改

一、el-table新增合計行以及el-table展示數據出現的問題 1. 使用合計行 el-table的屬性show-summary設為true&#xff0c;即可在表格尾部展示合計行。默認情況下&#xff0c;第一列不展示數據&#xff0c;而顯示合計二字&#xff0c;可以通過sum-text自己配置&#xff0c;其余…

olmOCR:高效精準的 PDF 文本提取工具

在日常的工作和學習中&#xff0c;是否經常被 PDF 文本提取問題困擾&#xff1f;例如&#xff1a; 想從學術論文 PDF 中提取關鍵信息&#xff0c;卻發現傳統 OCR 工具識別不準確或文本格式混亂&#xff1f;需要快速提取商務合同 PDF 中的條款內容&#xff0c;卻因工具不給力而…