C#中的托管资源与非托管资源介绍
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<string> list = new List<string> { "a", "b" };User user = new User { Name = "Test" };// 使用资源Console.WriteLine(string.Join(",", list));Console.WriteLine