【C#】内存的使用和释放

10,193次阅读
没有评论

共计 2238 个字符,预计需要花费 6 分钟才能阅读完成。

在 C# 中,内存管理主要是由 .NET 的垃圾回收器(Garbage Collector, GC)自动处理的。然而,了解如何正确地使用和释放内存对于编写高效且可靠的代码非常重要。以下是一些关键点和最佳实践:

1. 内存分配

  1. 托管资源

    • 托管资源是由 CLR 自动管理的,例如对象实例、字符串等。
    • 当创建一个对象时,CLR 会从托管堆中分配内存。
  2. 非托管资源

    • 非托管资源包括文件句柄、数据库连接、GDI+ 对象等。
    • 这些资源需要显式地释放,通常通过实现 IDisposable 接口来完成。

2. 内存释放

  1. 垃圾回收器

    • 垃圾回收器定期运行,查找不再被引用的对象,并回收它们占用的内存。
    • 垃圾回收器将内存分为三代(Gen 0, Gen 1, Gen 2),根据对象的生命周期进行不同的处理。
  2. 终结器(Finalizer)

    • 终结器是一个特殊的方法,用于在对象被垃圾回收之前执行清理工作。
    • 终结器通常用于释放非托管资源,但不推荐频繁使用,因为它们会增加垃圾回收的复杂性和开销。
  3. IDisposable 接口

    • 实现 IDisposable 接口可以显式地控制资源的释放。
    • 使用 using 语句可以确保资源在作用域结束时被正确释放。

3. 示例代码

3.1 托管资源的使用和释放

public class ManagedResource
{
    // 构造函数
    public ManagedResource()
    {Console.WriteLine("ManagedResource created.");
    }

    // 析构函数(可选)~ManagedResource()
    {Console.WriteLine("ManagedResource finalized.");
    }
}

public class Program
{static void Main()
    {ManagedResource resource = new ManagedResource();
        // 使用资源...
        
        // 资源会在适当的时候被垃圾回收器自动回收
    }
}

3.2 非托管资源的使用和释放

using System;

public class UnmanagedResource : IDisposable
{
    private IntPtr _handle; // 模拟非托管资源
    private bool _disposed = false;

    public UnmanagedResource()
    {
        _handle = IntPtr.Zero; // 分配非托管资源
        Console.WriteLine("UnmanagedResource created.");
    }

    public void Dispose()
    {Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    {if (!_disposed)
        {if (disposing)
            {// 释放托管资源}

            // 释放非托管资源
            if (_handle != IntPtr.Zero)
            {
                // 释放非托管资源
                Console.WriteLine("UnmanagedResource released.");
                _handle = IntPtr.Zero;
            }

            _disposed = true;
        }
    }

    ~UnmanagedResource()
    {Dispose(false);
    }
}

public class Program
{static void Main()
    {using (var resource = new UnmanagedResource())
        {// 使用资源...}

        // 资源在 using 语句块结束时被自动释放
    }
}

4. 最佳实践

  1. 使用 using 语句

    • 对于实现了 IDisposable 接口的对象,使用 using 语句确保资源在作用域结束时被正确释放。
  2. 避免不必要的对象创建

    • 尽量减少临时对象的创建,特别是在循环中。
  3. 及时释放非托管资源

    • 如果类使用了非托管资源,确保实现 IDisposable 接口,并在 Dispose 方法中释放这些资源。
  4. 避免显式调用 GC.Collect()

    • 除非有明确的理由,否则不要显式调用 GC.Collect(),因为这会影响性能并干扰垃圾回收器的正常工作。
  5. 避免滥用终结器

    • 只有在确实需要释放非托管资源时才使用终结器。大多数情况下,应优先使用 IDisposable 接口。
  6. 使用弱引用

    • 对于那些可以被垃圾回收器回收的对象,可以考虑使用 WeakReference 类,以避免强引用导致对象无法被回收。

通过遵循这些最佳实践,可以更有效地管理和优化 C# 应用程序中的内存使用。

5. 解决内存已损坏

【C#】未处理 System.AccessViolationExceptionHResult=-2147467261Message= 尝试读取或写入受保护的内存。这通常指示其他内存已损坏。_system.accessviolationexception:“尝试读取或写入受保护的内存。这通常 -CSDN 博客 文章浏览阅读 1.3k 次,点赞 9 次,收藏 10 次。【C#】未处理 System.AccessViolationExceptionHResult=-2147467261Message= 尝试读取或写入受保护的内存。这通常指示其他内存已损坏。_system.accessviolationexception:“尝试读取或写入受保护的内存。这通常指示其他【C#】内存的使用和释放https://blog.csdn.net/wangnaisheng/article/details/139679402

 

原文地址: 【C#】内存的使用和释放

    正文完
     0
    Yojack
    版权声明:本篇文章由 Yojack 于2024-09-30发表,共计2238字。
    转载说明:
    1 本网站名称:优杰开发笔记
    2 本站永久网址:https://yojack.cn
    3 本网站的文章部分内容可能来源于网络,仅供大家学习与参考,如有侵权,请联系站长进行删除处理。
    4 本站一切资源不代表本站立场,并不代表本站赞同其观点和对其真实性负责。
    5 本站所有内容均可转载及分享, 但请注明出处
    6 我们始终尊重原创作者的版权,所有文章在发布时,均尽可能注明出处与作者。
    7 站长邮箱:laylwenl@gmail.com
    评论(没有评论)