gpt4 book ai didi

c# - 垃圾收集和使用 - 为什么内存在 `using{}` block 之后没有释放?

转载 作者:行者123 更新时间:2023-11-30 13:36:45 25 4
gpt4 key购买 nike

我最近一直在重构一些旧的数据库访问代码。我有一个包含数百种方法的库,看起来像这样

public int getFoo(int id)
{
using(SqlConnection connection = ConnectionManager.GetConnection())
{
string sql = "SELECT TOP(1) foo FROM bar WHERE id=@id";

SqlCommand command = new SqlCommand(sql, connection);
command.Parameters.AddWithValue("@id", id);
return (int)command.ExecuteScalar();
}
}

我认为将 SqlCommand 包装到 using{} block 中是明智的做法(就像 SqlConnection 已经是这样)以便尽快处理资源。出于求知欲,我决定制作以下小型控制台应用程序以查看将释放多少内存:

using (SqlConnection conn = ConnectionManager.GetConnection())
{
WeakReference reference;
string sql = "SELECT COUNT(foo) FROM bar";
Console.WriteLine("Memory Allocated before SqlCommand: " + GC.GetTotalMemory(true));
using (SqlCommand comm = new SqlCommand(sql,conn))
{
Console.WriteLine("Memory Allocated after SqlCommand: " + GC.GetTotalMemory(true));
reference = new WeakReference(comm);

Console.WriteLine("SQL output: " + comm.ExecuteScalar());

Console.WriteLine(
"Memory Allocated before dispose SqlCommand: " + GC.GetTotalMemory(true));
}
GC.Collect();
Console.WriteLine("Memory Allocated after SqlCommand: " + GC.GetTotalMemory(true));
Console.WriteLine("Reference is alive: " + reference.IsAlive);

Console.ReadLine();
}

令我惊讶的是,这是我得到的输出:

Memory Allocated before SqlCommand: 236384

Memory Allocated after SqlCommand: 239160

SQL output: (whatever)

Memory Allocated before dispose SqlCommand: 246416

Memory Allocated after dispose SqlCommand: 246548 <-- It's gone up!?

Reference is alive: True <-- Why is reference still alive?

起初我虽然我的 WeakReference 可能以某种方式使 command 保持事件状态,但我注释掉了该代码,但我仍然得到了类似的结果。

为什么 command 在这里没有被垃圾回收,即使 GC.Collect() 已被显式调用?如果在 using block 中引入了一个变量,我们什么时候可以期望该变量有资格进行垃圾回收?

最佳答案

对象的处置与垃圾收集无关。垃圾收集与清理托管 资源有关。 Disposal 用于清理 GC 未跟踪非托管 资源。

有时,这些非托管资源是在不通过 GC 的情况下显式分配的内存,有时它们锁定在文件句柄、数据库连接、网络套接字或任何数量的其他可能性上。但无论它们是什么,它们都非常明确地不会成为 GC 正在跟踪的内存,而这正是您正在测量的内存。

就差异而言,您的差异只是在程序的噪音水平内。您的更改不会对使用的托管内存量产生有意义的影响,并且您看到的差异与使用垃圾回收的程序中内存的正常波动一致。

关于c# - 垃圾收集和使用 - 为什么内存在 `using{}` block 之后没有释放?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30353809/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com