.NET 内存管理两种有效的资源释放方式

简介: 【10月更文挑战第14天】在 .NET 中,`IDisposable` 接口提供了一种标准机制来释放非托管资源,如文件句柄、数据库连接等。此类资源需手动释放以避免泄漏。实现 `IDisposable` 的类可通过 `Dispose` 方法释放资源。使用 `using` 语句可确保资源自动释放。此外,.NET 的垃圾回收器会自动回收托管对象所占内存,提高程序效率。示例代码展示了如何使用 `MyFileHandler` 类处理文件操作并释放 `FileStream` 资源。
  1. 使用Dispose方法(实现IDisposable接口)
  • 接口介绍
  • 在.NET 中,IDisposable接口提供了一种标准的机制来释放非托管资源。非托管资源包括文件句柄、数据库连接、网络套接字等。这些资源不受.NET 垃圾回收器(Garbage Collector,GC)的直接控制,需要手动进行释放,以避免资源泄漏。
  • 实现IDisposable接口的类示例(以文件流为例)
  • 当使用FileStream类读取或写入文件时,它会占用系统资源,如文件句柄。


class MyFileHandler : IDisposable
{
    private FileStream _fileStream;
    public MyFileHandler(string filePath)
    {
        _fileStream = new FileStream(filePath, FileMode.Open);
    }
    public void ReadData()
    {
        // 读取文件数据的逻辑
        byte[] buffer = new byte[1024];
        _fileStream.Read(buffer, 0, buffer.Length);
    }
    public void Dispose()
    {
        _fileStream.Dispose();
    }
}



- 在上述代码中,`MyFileHandler`类用于处理文件操作。在构造函数中,它打开一个`FileStream`来读取文件。`Dispose`方法被实现,用于释放`FileStream`占用的资源。
   - **使用`using`语句块进行资源释放**:
     - `using`语句是一种方便的语法糖,它可以确保在代码块执行完毕后自动调用`Dispose`方法。
     - ```csharp
       class Program
       {
           static void Main()
           {
               using (MyFileHandler fileHandler = new MyFileHandler("test.txt"))
               {
                   fileHandler.ReadData();
               }
               // 当离开using块时,fileHandler的Dispose方法会自动被调用
           }
       }


  • 在这个示例中,当using语句块中的代码执行完毕后,MyFileHandler对象的Dispose方法会被自动调用,从而释放FileStream资源。


  1. 通过垃圾回收器(Garbage Collector)自动回收
  • 垃圾回收器工作原理
    -.NET 的垃圾回收器是一种自动内存管理机制。它会定期扫描托管堆(Managed Heap),识别那些不再被程序引用的对象。一旦确定对象不再被引用,垃圾回收器就会回收这些对象占用的内存空间,将其标记为可用空间,以便后续分配给新的对象使用。
  • 触发垃圾回收的情况
  • 垃圾回收器会根据一定的算法和条件来决定何时进行回收。一般来说,当托管堆的内存使用达到一定阈值时,垃圾回收器会被触发。另外,某些情况下,如程序主动调用GC.Collect()方法(虽然不建议频繁使用,因为这可能会影响性能),也会触发垃圾回收。
  • 例如,在一个包含大量对象创建和销毁的应用程序中,垃圾回收器会自动管理内存。假设我们有一个简单的控制台应用程序,它会不断创建和销毁字符串对象:


class Program
{
    static void Main()
    {
        for (int i = 0; i < 10000; i++)
        {
            string myString = "Test String " + i;
            // 这里myString对象在每次循环结束后,可能会被垃圾回收
        }
    }
}



- 在这个循环中,每次创建的`string`对象在循环结束后,如果没有其他引用指向它,就会成为垃圾回收器回收的候选对象。垃圾回收器会在适当的时候回收这些字符串对象占用的内存。
   - **优化垃圾回收性能**:
     - 虽然垃圾回收器是自动工作的,但开发者可以采取一些措施来优化其性能。
相关文章
|
19天前
|
开发框架 监控 .NET
【Azure App Service】部署在App Service上的.NET应用内存消耗不能超过2GB的情况分析
x64 dotnet runtime is not installed on the app service by default. Since we had the app service running in x64, it was proxying the request to a 32 bit dotnet process which was throwing an OutOfMemoryException with requests >100MB. It worked on the IaaS servers because we had the x64 runtime install
|
2月前
|
机器学习/深度学习 算法 物联网
大模型进阶微调篇(一):以定制化3B模型为例,各种微调方法对比-选LoRA还是PPO,所需显存内存资源为多少?
本文介绍了两种大模型微调方法——LoRA(低秩适应)和PPO(近端策略优化)。LoRA通过引入低秩矩阵微调部分权重,适合资源受限环境,具有资源节省和训练速度快的优势,适用于监督学习和简单交互场景。PPO基于策略优化,适合需要用户交互反馈的场景,能够适应复杂反馈并动态调整策略,适用于强化学习和复杂用户交互。文章还对比了两者的资源消耗和适用数据规模,帮助读者根据具体需求选择最合适的微调策略。
160 5
|
2月前
|
数据库连接 开发者
.NET 内存管理两种有效的资源释放方式
【10月更文挑战第15天】在.NET中,有两种有效的资源释放方式:一是使用`using`语句,适用于实现`IDisposable`接口的对象,如文件流、数据库连接等,能确保资源及时释放,避免泄漏;二是手动调用`Dispose`方法并处理异常,提供更灵活的资源管理方式,适用于复杂场景。这两种方式都能有效管理资源,提高应用性能和稳定性。
|
3月前
|
缓存 Java 测试技术
谷粒商城笔记+踩坑(11)——性能压测和调优,JMeter压力测试+jvisualvm监控性能+资源动静分离+修改堆内存
使用JMeter对项目各个接口进行压力测试,并对前端进行动静分离优化,优化三级分类查询接口的性能
101 10
谷粒商城笔记+踩坑(11)——性能压测和调优,JMeter压力测试+jvisualvm监控性能+资源动静分离+修改堆内存
|
3月前
|
存储 运维
.NET开发必备技巧:使用Visual Studio分析.NET Dump,快速查找程序内存泄漏问题!
.NET开发必备技巧:使用Visual Studio分析.NET Dump,快速查找程序内存泄漏问题!
|
4月前
|
开发框架 前端开发 .NET
究竟是什么让.NET 开发者社区拥有如此强大的力量?资源、分享还是成长的秘密?
【8月更文挑战第28天】.NET开发者社区为成员提供了丰富的资源、积极的分享氛围和广阔的成长空间,是一个充满活力的知识宝库。在这里,从前沿的开源项目到深入的技术解析应有尽有,无论你是新手还是专家,都能找到适合自己的学习与交流机会,共同推动.NET技术的发展。
41 5
|
4月前
|
缓存 Kubernetes 数据中心
在Docker中,如何控制容器占用系统资源(CPU,内存)的份额?
在Docker中,如何控制容器占用系统资源(CPU,内存)的份额?
|
4月前
|
开发框架 监控 .NET
|
4月前
|
存储 编译器 C语言
【C语言篇】数据在内存中的存储(超详细)
浮点数就采⽤下⾯的规则表⽰,即指数E的真实值加上127(或1023),再将有效数字M去掉整数部分的1。
392 0