C#中的托管资源与非托管资源介绍
一、托管资源与非托管资源是什么
二、两者特点与区别
三、开发注意事项
四、实战 Demo:托管资源和非托管资源的使用示例
示例1:纯托管资源的使用
示例2:非托管资源的using释放
示例3:自定义非托管资源的IDisposable实现
总结
C#中的托管资源与非托管资源介绍
在C#开发中,根据是否受.NET运行时(CLR)管理,资源分为托管资源和非托管资源。理解两者差异对防止内存泄漏、保障程序稳定性很有帮助
一、托管资源与非托管资源是什么
托管资源:由CLR全程管理的对象(如string、List、自定义类实例等)。其生命周期(创建、内存分配、回收)完全由垃圾回收器(GC)负责,开发者不需要手动干预
非托管资源:不受CLR管理的底层资源(如文件句柄、数据库连接、网络套接字、Windows API句柄等),由操作系统分配,GC无法识别和回收,必须手动释放,否则会导致内存泄漏
二、两者特点与区别
对比项
托管资源
非托管资源
管理主体
.NET CLR(垃圾回收器GC)
操作系统 + 开发者手动管理
内存处理
GC自动分配(new)、自动回收
操作系统分配,需手动释放
类型安全
受CLR检查(防类型错误、内存越界)
无类型安全检查(需开发者保证)
释放责任
GC自动处理(开发者无需干预)
开发者必须显式释放
泄漏风险
低(GC回收未引用对象)
高(忘记释放则长期占用资源)
典型示例
List、自定义类实例
文件流(FileStream)、数据库连接、IntPtr句柄
三、开发注意事项
非托管资源必须手动释放:GC仅回收托管资源,非托管资源(如文件流)需手动释放,不然系统资源迟早被耗光
优先使用using语句:对于实现IDisposable接口的非托管资源对象(如FileStream),用using包裹其代码块,代码块结束后会自动调用Dispose()释放资源,即使发生异常也能保证执行
自定义非托管资源需实现IDisposable:要是自己实现的类里包含非托管资源(如通过P/Invoke获取的句柄),必须实现IDisposable接口,这样才能保证资源正确释放,还能避免重复回收
纯托管资源无需手动释放:像List等纯托管资源,不要用using或Dispose(),交给 GC 就好了,多余的代码不仅影响可读性,还可能降低效率
四、实战 Demo:托管资源和非托管资源的使用示例
示例1:纯托管资源的使用
using System;
using System.Collections.Generic;
class ManagedExample
{
// 自定义托管类
public class User {
public string Name {
get; set; } }
static void Main()
{
// 创建托管资源(GC自动管理)
List
"a", "b" };
User user = new User {
Name = "Test" };
// 使用资源
Console.WriteLine(string.Join(",", list));
Console.WriteLine