43.托管内存和非托管内存

  1. 43.托管内存和非托管内存
    1. 43.1 题目
    2. 43.2 深入解析
      1. 托管内存
      2. 非托管内存
    3. 43.3 答题示例
    4. 43.4 关键词联想

43.托管内存和非托管内存


43.1 题目

C#中什么是托管内存和非托管内存?


43.2 深入解析

托管内存

托管内存是由.NET运行时(CLR,Common Language Runtime)进行管理的内存。C#中大部分对象都是托管内存,它们的内存分配、回收和资源管理都由CLR负责。CLR 提供垃圾回收(GC)回收托管堆上不再可达的对象;但 GC 直接回收文件句柄、套接字等 OS 资源,这类资源常通过 IDisposable 显式释放。

例如,我们平时声明的引用类型的变量都属于托管内存:

// 这是一个托管内存的示例
public class Example
{
    public string Name { get; set; }
}

Example example = new Example();

非托管内存

非托管内存是由应用程序自己负责管理的内存,通常是通过调用本机API或与外部系统进行交互时使用的。非托管内存不受CLR的管理,这意味着它不会受到垃圾回收的影响。开发人员需要自己负责内存的分配和释放,否则可能会导致内存泄漏或者访问无效内存的问题。

需区分:托管对象(如 FileStreamSqlConnection)本身在托管堆上,由 GC 回收;它们内部封装的 OS 句柄/非托管指针 仍须通过 Dispose/Close 释放。真正直接操作非托管堆块时,常用 Marshal.AllocHGlobal 等 API,并配对 Freeunsafe/stackalloc 则涉及栈上非托管内存,语义与托管堆不同。

// 这是一个非托管内存的示例
public unsafe class UnsafeExample
{
    public void UsePointer()
    {
        int* p = stackalloc int[10];
        // 使用指针进行操作
    }
}

对于非托管资源,我们需要使用如IDisposable接口来手动释放资源:

// 这是一个非托管内存的示例,使用IDisposable接口
public class UnmanagedResource : IDisposable
{
    private IntPtr unmanagedPointer;
    
    public UnmanagedResource()
    {
        // 分配非托管内存
        unmanagedPointer = Marshal.AllocHGlobal(100);
    }

    public void Dispose()
    {
        // 释放非托管内存
        if (unmanagedPointer != IntPtr.Zero)
        {
            Marshal.FreeHGlobal(unmanagedPointer);
            unmanagedPointer = IntPtr.Zero;
        }
    }
}

// 使用非托管资源
UnmanagedResource resource = new UnmanagedResource();
resource.Dispose();

在上面的例子中,我们通过实现IDisposable接口来确保在不再需要UnmanagedResource对象时正确地释放非托管内存。


43.3 答题示例

  1. 托管内存:由.NET运行时(CLR)自动管理的内存,其分配、回收(通过垃圾回收机制GC)均由CLR负责,无需开发者手动操作,能减少内存泄漏风险,常见于引用类型(如类、字符串)的实例存储。
  2. 非托管内存:不受CLR管理的内存,需开发者手动分配(如通过Marshal.AllocHGlobal)和释放(如通过Marshal.FreeHGlobal或实现IDisposable接口),若管理不当易导致内存泄漏,常见于指针操作、非托管资源(如文件流、数据库连接)的存储。

43.4 关键词联想

托管内存:CLR、垃圾回收(GC)、自动管理、安全、引用类型、堆
非托管内存:手动管理、Marshal、IDisposable、指针、内存泄漏、非托管资源
核心区别:管理主体(CLR vs 开发者)、回收方式(自动 vs 手动)



转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 785293209@qq.com

×

喜欢就点赞,疼爱就打赏