C#垃圾回收、析构与IDisposable

88 阅读2分钟

GC

明确数据的存放内存 stack栈内存:速度快、效率高。类型大小有限制,只能保存简单的数据,基础数据类型、值类型 Heap堆内存:结构复杂的数据,对象 引用类型:变量保存的是内存地址的引用(在栈中)。 垃圾回收工作原理:如果一段内存的引用数量为0,则代表对象的生命周期结束

分代回收

Gen0 Gen1 Gen2 暂时性的对象 中长期对象 长期对象 每次运行Gc都检查 检查频率下降 GC偶尔来检查 如果发现对象一直被引用就转移到gen1 同理转移到gne2 内存不足时,GC会强行清理所有对象 GC还会标记清理内存中死掉的对象,并且压缩内存,消除间隙,提高对象创建,读取效率 GC针对不同类型对象回收会有不同的触发时机,内存压力较大就会触发垃圾回收 GC自主权很大,自动部分回收或者全部回收 GC运行在独立线程,每次运行都会消耗计算资源

析构方法与终结器

若无必要,不要使用 终结器无法直接调用,在对象生命周期结束后等待垃圾回收自动调用。即使声明了终结器,依然有可能不被调用,因此要避免外部资源(如数据库的连接等)在此处回收

~类名(){
//todo
}

//等待所有需要被回收的对象全部回收
GC.WaitForPendingFinalizers();
//垃圾回收
GC.Collect();

官方文档对此有很明确的说明 终结器 - C# 编程指南 | Microsoft Learn 一个类只有一个终结器,不能被继承或重载,终结器不使用修饰符和参数

Disposable模式

网络连接,数据库连接,文件访问等外部资源无法自动回收

IDisposable

public interface IDisposable
{
    void Dispose();
}
//实现了IDisposable接口相当于告诉代码这里有非托管资源,需要在使用后手动清理和释放
public class Custom : IDisposable
{
    void Method();
    void Dispose();
}
//使用dispose需要使用using关键字
static main(){
    using(var obj = new Custom()){
        obj,Method();
    }
}
相当于
static main(){
    var obj = new Custom()
    try {
    obj.Method();
    }
    finally{
    obj.Dispose();
    }
}