1.
2. string 在内存中是连续分配的,是一个数组, 数组的特点就是 查询块,增删慢,改动Array导致所有数组成员地址变动,成本高 而string又是在程序中经常变动的 ,所有 clr中对 string 这种引用类型做特殊处理, 使用字面量声明 string时, 会先到string驻留池中查找 要声明的值有无,有直接把 池中实例地址返回 赋值给变量 .无则 新增
3. CLR的内存分配
4. GC 相关
析构函数 类型名称价加个~ 单独的处理,把这些对象放入一个队列单独处理,但是不知道什么时候去调用后析构函数
主要是用来释放非托管资源
析构函数 与 Dispose() 都是用来非托管资源的 , 有什么区别
被动 主动释放
如下图代码, using 代码块结束后, 会调用student的 dispose方法
如果 项目中需要封装一些 非托管资源供别人调用 , 实现Idispose接口的 一般逻辑是: 参考下 Student 类的实现
1. 假如别人用我的代码时 使用了dispose() 方法来释放资源, 手动调用 GC.SuppressFinalize(this) 告诉GC 不需要你来释放了 (提供主动释放方式,最快释放非托管资源)
2. 如果使用我代码的 没调用 dispose() , Student中的 析构函数 确保该资源能被 GC 回收 (保底)
public class People : IDisposable
{
public string Remark { get; set; }
public virtual void Dispose()
{
MyLog.Log($"执行{this.GetType().Name}Dispose");
}
} public class Student : People, IDisposable
{
public int Id { get; set; }
public string Name { get; set; }
public Class Class { get; set; } public override void Dispose()//提供主动释放方式
{
base.Dispose();//把我引用的其他东西给清理掉
if (this.Class != null)
{
this.Class.Dispose();
}
//通知垃圾回收机制不再调用终结器(析构器)
GC.SuppressFinalize(this);
MyLog.Log($"执行{this.GetType().Name}Dispose");
} public void Study()
{
Console.WriteLine("跟着Eleven老师学习.Net高级开发");
} ~Student()//保证垃圾回收时 一定会把非托管资源释放
{
MyLog.Log($"执行{this.GetType().Name}Dispose");
}
} public class Class : IDisposable
{
public int ClassId { get; set; }
public string ClassName { get; set; }
//~Class()
//{
// MyLog.Log($"执行{this.GetType().Name}Dispose");
//}
public void Dispose()
{
MyLog.Log($"执行{this.GetType().Name}Dispose");
}
}