垃圾回收

在了解垃圾回收之前我们需要了解几个概念
 
托管资源:主要是有CLR分配和释放的资源
非托管资源:不受CLR控制,也就是不属于.net本身的功能 eg: 数据库连接,磁盘文件读写,Socket,Win32API,Window内核对象,网络Http*
析构函数:当对象脱离其作用域时(例如对象所在的函数已调用完毕),系统自动执行析构函数
 
问题一:
.net 已经为我们在将近100个类实现了IDisposable接口(非托管的),那么我们为啥在使用这些类的时候还需要显式释放?
根据垃圾回收机制,这个垃圾回收并不是实时的,而是分等级的,分条件的具体看:
你不主动释放,若还有别人也想访问这个资源就会出错,所以建议你使用完了就及时释放,拉完屎就出来;你影响了公共厕所的高效率运行,我需要你确定性释放,而不是你释放到了一个不太规律的时间段内;
 
当然有很多时候你短时间内只使用一次那么是不用管的,它会在你
 
 
 
 
问题二:
根据问题一,既然需要主动释放,那么应该怎么样,使用using也就是trycatchfinally 在Java中你使用到那些非托管 不写会直接报错的;
eg:使用实现 IDisposable 的对象
using()
using()
{}
 
eg2: 当你直接使用Win32API 等未被CLR封装实现Idispose时 应该怎么处理?
使用安全句柄包装非托管资源
 
 
问题三:
在Finally中,是否需要判断为null if (sr != null) sr.Dispose();
必须检查,不然会发生Null异常,当然大部分情况下我们都会给对象赋值的,养成好习惯
 
 
/// <summary>
/// 释放标记
/// </summary>
private bool disposed;
 
/// <summary>
/// 为了防止忘记显式的调用Dispose方法
/// </summary>
~TcpServer()
{
//必须为false
Dispose(false);
}
 
/// <summary>执行与释放或重置非托管资源关联的应用程序定义的任务。</summary>
public void Dispose()
{
//必须为true
Dispose(true);
//通知垃圾回收器不再调用终结器
GC.SuppressFinalize(this);
}
 
/// <summary>
/// 非密封类可重写的Dispose方法,方便子类继承时可重写
/// </summary>
/// <param name="disposing"></param>
protected virtual void Dispose(bool disposing)
{
if (disposed)
{
return;
}
 
//清理托管资源
if (disposing)
{
 
}
 
//清理非托管资源
if (m_SocketListener != null)
{
m_SocketListener.Close(2);
m_SocketListener.Dispose();
}
//告诉自己已经被释放
disposed = true;
}
posted @ 2020-01-15 23:32  maanshancss  阅读(103)  评论(0编辑  收藏  举报