我正在使用IDisposable接口和GC,有些东西我无法理解。
所以我们有以下课程:
public class DatabaseState : IDisposable
{
protected SqlConnection _connection;
public virtual string GetDate()
{
if (_disposed)
throw new ObjectDisposedException("DatabaseState");
if (_connection == null)
{
var connectionString = ConfigurationManager.ConnectionStrings["master"];
_connection = new SqlConnection(connectionString.ConnectionString);
_connection.Open();
}
using (var command = _connection.CreateCommand())
{
command.CommandText = "SELECT getdate()";
return command.ExecuteScalar().ToString();
}
}
private bool _disposed;
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (_disposed)
return;
if (disposing)
{
if (_connection != null)
{
_connection.Dispose();
_connection = null;
}
_disposed = true;
}
}
}
您可以看到该类非常简单(仅获取当前日期)。
在Main中,我有以下代码:
class Program
{
static void Main(string[] args)
{
Console.WriteLine("'g' to Get Date; 'gc' to Garbage Collect; 'x' to Exit");
var command = "";
while (command != "x")
{
command = Console.ReadLine();
switch (command)
{
case "g":
GetDate();
break;
case "gc":
GC.Collect();
break;
}
}
}
private static void GetDate()
{
using (var databaseState = new DatabaseState())
//var databaseState = new DatabaseState();
{
Console.WriteLine(databaseState.GetDate());
}
}
}
第一个实验是当我使用IDisposable和(我在诊断工具中使用VS build。)
查看以下快照:
数字代表快照ID。
从现在开始,奇怪的事情发生在我身上。
4、5、6、7我也按了“ g”。如您所见,我们尚未分配任何内存。这是我的第一个问题,为什么?。
我按下了“ gc”,这强制了GC.Collect()。那时我很惊讶。我们尚未释放任何记忆。据我所知,GC.Collect()释放了各代人的记忆。第二个问题为什么此时GC尚未释放任何内存?
我再次按下“ g”。与快照4、5、6和7中的情况相同。我们尚未分配任何内存。 为什么?
10、11个随机创建的快照。
这也很有趣。我尚未执行任何操作,某些内容已分配了2.4 KB内存。我再次检查了我们创建的对象类型:ContextCallback,Microsoft.Win32.SafeHandles.SafeFileMappingHandle,AppDomainPauseManager,ThreadPoolWorkQueue。同样,我不熟悉这些类型,但我认为它们与CLR有关。
与12相同。我已经有一段时间没有执行任何操作了,但是这次我们释放了20.66 KB的内存。 为什么?
总结:
据我了解,IDisposable和GC应该以一些不同的方式工作。 第一次实例化DatabaseState时,我应该打开连接,握手等。因此,我们将分配更多的内存。 由于我们在using语句中使用DatabaseState实例,因此我们将释放这些非托管资源。下次当我使用DatabaseState实例时,我应该为该实例分配一些内存(但是从快照4,5、6、7和9中我没有分配任何内存)仅为该实例分配,因为连接,握手已经完成了。
我丢失了一些东西,但是我不知道在哪里和什么地方。
致谢