前言

嗨,大家好!今天我们要聊一聊 .NET 中的内存管理。你知道吗?虽然 .NET 有一个很好的垃圾回收系统来自动清理不再使用的对象,但在某些情况下,我们还需要自己动手来释放一些特殊的资源,比如打开的文件或数据库连接。如果不这样做,可能会导致程序运行不畅甚至崩溃。在本文里,将介绍两种简单有效的方式来管理这些资源:使用 using 语句和显式调用 Dispose 方法。这两种方式可以我们更有效地控制资源的生命周期,避免内存泄漏等问题,确保应用程序的健壮性。不管是刚入门的小白还是技术大牛,希望你能从这篇文章中学有用的知识和技巧,让我们的程序运行的更稳、更靠谱。

正文

在 .NET 中内存管理主要依赖于垃圾回收机制,主要是指内存管理和非托管资源的释放。但是,有时候我们可能需要更细粒度地控制某些资源的释放。两种主要的方式进行处理

  • 垃圾回收(GC)
  • 确认性资源释放(DRD)

官网相关文档https://learn.microsoft.com/zh-cn/dotnet/standard/managed-code

垃圾回收(Garbage Collection)

垃圾回收是 .NET 中一个非常重要的自动内存管理机制。它帮助我们自动清理不再使用的对象,并释放这些对象占用的内存,避免了手动管理内存的繁琐的工作,使我们能够更加专注于编写业务逻辑。

1、为什么需要垃圾回收?

  • 避免内存泄漏:垃圾回收自动检测不再使用的对象,并释放它们占用的内存空间。
  • 简化代码:无需手动释放内存,减少了代码中的错误和负担。

2、垃圾回收有哪些特点?

  • 自动运行,不需要开发者显性调用
  • 当内存不足时触发
  • 释放托管内存(即通过.NET内村分配的内存)
  • 不保证立即释放内存,而是根据内存压力情况周期性地进行

3、垃圾回收有什么局限性?

  • 无法处理非托管资源,如文件句柄、数据库链接、图形设备接口(GDI)对象等
  • 可能会导致应用程序出现短暂的暂停(GC暂停)

4、垃圾回收需要注意什么?

  • 尽量避免大对象堆:大对象会直接分配到大对象堆,可能会导致垃圾回收器更频繁地工作。
  • 适时调用 GC.Collect():虽然大多数情况下不需要手动触发垃圾回收,但在某些特殊场景下,如长时间运行的应用程序,可以考虑适时调用 GC.Collect() 来帮助回收内存。

确定性资源释放

对于非托管资源.NET提供了确定性的资源释放机制,通常通过IDisposable接口实现。

1、使用 using 语句

.NET 提供了 IDisposable 接口来帮助管理非托管资源(例如文件句柄、数据库连接等)。

使用using语句来自动释放实现IDsposable的对象所持有的资源,使用 using 语句可以确保即使在发生异常的情况下也能正确释放资源。

实例中StreamReader实现了IDsposable接口。

通过使用using语句,当StreamReader对象超出作用域时,Dispose方法会被自动调用,从而释放文件句柄。

using System;
using System.IO;
class Program
{
static void Main()
{
using (var stream = new FileStream("demo.txt", FileMode.Open))
{
byte[] buffer = new byte[1024];
int bytesRead = stream.Read(buffer, 0, buffer.Length);
// 处理读取的数据
}
// 文件流会自动关闭
}
}

2、显式调用 Dispose 方法

如果不能使用 using 语句(例如在循环中或其他复杂情况下),可以手动调用 Dispose 方法来释放资源。当一个对象实现了IDsposable接口,意味着它持有需要手动释放的资源,实现IDsposable的对象必须重写Dispose方法来清理非托管缓存。

using System;
using System.IO;
class Program
{
static void Main()
{
FileStream stream = new FileStream("demo.txt", FileMode.Open);
try
{
byte[] buffer = new byte[1024];
int bytesRead = stream.Read(buffer, 0, buffer.Length);
// 处理读取的数据
}
finally
{
stream.Dispose();
}
}
}

总结

好了,我们今天聊了聊 .NET 中的内存管理。通过使用 using 语句和显式调用 Dispose 方法,我们可以更好地控制那些特殊的资源,比如文件和数据库连接。这样不仅能避免程序出错,还能让我们的程序运行得更加顺畅。

如果你觉得这篇文章对你有帮助,不妨点个赞支持一下!你的支持是我继续分享知识的动力。如果有任何疑问或需要进一步的帮助,欢迎随时留言。

也可以加入微信公众号 [DotNet技术匠] 社区,与其他热爱技术的同行一起交流心得,共同成长!

.NET 内存管理两种有效的资源释放方式的更多相关文章

  1. c#内存管理,垃圾回收和资源释放

    <1>关于虚拟内存的概念 Windows使用一个虚拟寻址系统,该系统把程序可用的内存地址映射到硬件内存中的实际地址上去,这些任务完全由windows后台管理,其实际结果是32位处理机上的每 ...

  2. [Spark内核] 第31课:Spark资源调度分配内幕天机彻底解密:Driver在Cluster模式下的启动、两种不同的资源调度方式源码彻底解析、资源调度内幕总结

    本課主題 Master 资源调度的源码鉴赏 [引言部份:你希望读者看完这篇博客后有那些启发.学到什么样的知识点] 更新中...... 资源调度管理 任务调度与资源是通过 DAGScheduler.Ta ...

  3. Linux 服务管理两种方式service和systemctl

    Linux 服务管理两种方式service和systemctl 1.service命令 service命令其实是去/etc/init.d目录下,去执行相关程序 # service命令启动redis脚本 ...

  4. Linux进程分配内存的两种方式--brk() 和mmap()

    如何查看进程发生缺页中断的次数? 用ps -o majflt,minflt -C program命令查看. majflt代表major fault,中文名叫大错误,minflt代表minor faul ...

  5. 内存分配的原理__进程分配内存有两种方式,分别由两个系统调用完成:brk和mmap(不考虑共享内存)

    如何查看进程发生缺页中断的次数? 用ps -o majflt,minflt -C program命令查看. majflt代表major fault,中文名叫大错误,minflt代表minor faul ...

  6. 进程分配内存的两种方式--brk() 和mmap()(不设计共享内存)(转)

    如何查看进程发生缺页中断的次数? 用ps -o majflt,minflt -C program命令查看. majflt代表major fault,中文名叫大错误,minflt代表minor faul ...

  7. KbmMW两种查询结果集通讯方式

    KbmMW本身可以用QueryService的方式进行远程数据查询,但是SmpileService同样具有很强的扩展性可以实现数据查询,下面展示两种基于SmpileService的远程数据查询方法,其 ...

  8. reportConfig.xml两种数据源连接的配置方式

     在reportConfig.xml配置文件中,我们提供了两种数据源连接的配置方式,分别如下: 1.jndi数据源配置(即:在dataSource中配置) 此配置适用于在j2ee的服务器中配置了j ...

  9. 流式思想概述和两种获取Stream流的方式

    流式思想概述 整体来看,流式思想类似于工厂车间的生产流水线 当需要对多个元素进行操作(特别是多步操作)的时候,考虑到性能及便利性,我们应该首先拼好一个模型步骤方案,然后再按照方法去执行他 这张图中展示 ...

  10. 流思想概述-两种获取Stream流的方式

    流思想概述 注意:请暂时忘记对传统IO流的固有印象 ! 整体来看,流式思想类似与工厂车间的 '生产流水线'. 当需要对多个元素进行操作(特别是多步操作)的时候,考虑到性能及便利性,我们应该首先拼好一个 ...

随机推荐

  1. 【Hibernate】Re04 JPA规范使用

    都忘了前面一些小前提,就是数据库需要是存在的,不过写链接参数都会写上的 JPA实现就是和Hibernate类似,也需要对应的配置文件等等... 1.配置文件必须命名[persistence.xml]且 ...

  2. Typora配置自动上传图片到图床

      在多平台发布文章时,如果遇到图片不能导入的问题,推荐使用图床!推荐使用阿里云或腾讯云,免费的不用考虑了! PicGo下载 链接:https://pan.quark.cn/s/2ec95402631 ...

  3. 链接池偶尔报错:HikariPool-1 - Connection is not available, request timed out after 39985ms.

    1.背景 线上服务器偶尔报错如下: org.mybatis.spring.MyBatisSystemException: nested exception is org.apache.ibatis.e ...

  4. 词云图大师(WordCloudMaster)上线Web端!

    我们非常激动地宣布,词云图大师(WordCloudMaster)现已正式上线Web端!这一全新版本为用户带来了更多的便捷和功能,让创建和分享词云变得更加轻松.无论是企业.教育机构还是个人用户,都可以通 ...

  5. 深度解读KubeEdge架构设计与边缘AI实践探索

    摘要:解读业界首个云原生边缘计算框架KubeEdge的架构设计,如何实现边云协同AI,将AI能力无缝下沉至边缘,让AI赋能边侧各行各业,构建智能.高效.自治的边缘计算新时代,共同探索智能边缘的新篇章. ...

  6. 2024 睿抗机器人开发者大赛CAIP-编程技能赛-本科组(省赛)

    2024 睿抗机器人开发者大赛CAIP-编程技能赛-本科组(省赛) RC-u1 热҈热҈热҈ #include<bits/stdc++.h> using namespace std; us ...

  7. springboot代码自动生成

    在项目开始阶段经常需要自动生成一批代码,如果使用了mybatis则可以使用mybatis plus就可以生成mybatis相关代码.不过经常项目中还有一些mvc代码需要生成,比如说前端代码.相关sql ...

  8. Antd-React-TreeSelect前端搜索过滤

    在开发过程中,但是antd中的搜索会把多余的也会带出来 就例如下图,我们本想去搜索1但是他会把其子节点都带出来,其实我们的本意是像搜2一样或者当中间隔层处理 但是我们该如何解决这样的问题呢如何做到下面 ...

  9. MYSQL——帆软连接报错

    2024/07/11 1.报错 2.报错原因 3.解决办法 4.参考 1.报错 错误代码:11300001 数据集配置错误<br>Query:<br>Unknown initi ...

  10. freertos学习笔记(十)事件标志组

    事件标志组 相当于用户平时定义的Flag,事件标志,不过freertos支持将该标志组作为启动task的条件 概述 分为8位和24位的模式(通过设置宏来配置) 每一位有0和1两个状态 用法 用于平常程 ...