代码改变世界
2025-02-07 10:27
钟铧若岩
阅读(13)
评论()
编辑
收藏
举报
- 基本概念:垃圾回收(Garbage Collection,GC)是一种自动内存管理机制,旨在识别和回收不再被程序使用的内存空间,以便这些空间能被重新利用。
- 工作原理
- 对象引用计数:一些早期的垃圾回收算法会为每个对象维护一个引用计数,记录有多少个变量或对象引用了它。当一个对象的引用计数变为 0 时,就意味着没有任何变量或对象指向它,该对象就可以被视为垃圾,等待回收。
- 标记 - 清除算法:现代的垃圾回收算法多采用标记 - 清除的策略。垃圾回收器会从根对象(如全局变量、静态变量、当前执行方法的局部变量等)开始,递归地标记所有可以从根对象访问到的对象。标记完成后,未被标记的对象就是不可达的垃圾对象,垃圾回收器会遍历整个内存空间,清除这些垃圾对象所占用的内存。
- 分代回收:为了提高垃圾回收的效率,.NET 的垃圾回收器采用了分代的概念。将对象分为 0 代、1 代和 2 代。新创建的对象通常放在 0 代,随着垃圾回收的进行,未被回收的对象会被提升到更高的代。因为一般来说,新对象的生命周期较短,而老对象更有可能长期存活。所以对不同代的对象采用不同的回收频率和算法,可以提高整体的回收效率。
- 未正确释放非托管资源:在 C# 中,使用非托管资源(如文件句柄、网络连接、数据库连接等)时,如果没有正确地释放这些资源,就会导致内存泄露。比如,使用
FileStream
打开一个文件后,如果没有调用Close
或Dispose
方法关闭文件流,那么这个文件句柄就会一直被占用,直到进程结束。
- 事件注册导致的内存泄露:当一个对象 A 注册了对象 B 的某个事件,而对象 B 又持有对对象 A 的引用时,就可能导致循环引用。如果这种循环引用中的对象不再被其他地方使用,但因为相互引用而无法被垃圾回收器回收,就会造成内存泄露。
- 静态集合类导致的内存泄露:使用静态的集合类(如
List<T>
、Dictionary<TKey, TValue>
等)来存储大量对象时,如果这些对象在不再需要使用后没有从集合中移除,那么这些对象将一直被集合引用,无法被垃圾回收。
- 本地窗口句柄未释放:在进行一些与 Windows API 交互的操作时,可能会创建本地窗口句柄。如果在使用完这些句柄后没有正确地释放,就会导致内存泄露。因为这些本地资源不受 CLR 的直接管理,需要开发者手动进行释放。
- 线程相关的内存泄露:如果在一个线程中创建了大量的对象,并且这些对象在该线程执行完毕后没有被正确清理,就可能导致内存泄露。另外,如果线程持有对外部对象的强引用,而外部对象又引用了其他可能产生循环引用的对象,也可能导致内存泄露。
点击右上角即可分享
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 震惊!C++程序真的从main开始吗?99%的程序员都答错了
· 【硬核科普】Trae如何「偷看」你的代码?零基础破解AI编程运行原理
· 单元测试从入门到精通
· 上周热点回顾(3.3-3.9)
· winform 绘制太阳,地球,月球 运作规律