c# - 如何释放字典中对象使用的内存,还是不需要?
问题描述
我创建了一个类(下面的简化版本):
public class UsbDevice
{
public UsbDevice()
{
Debug.WriteLine($"UsbDevice constructor called");
}
~UsbDevice()
{
Debug.WriteLine($"UsbDevice destructor called");
}
}
我使用字典来保存我所有的 UsbDevices 的列表。
Dictionary<string, UsbDevice> _devices = new Dictionary<string, UsbDevice>();
UsbDevice usbDevice = new UsbDevice();
_devices.Add("Path of the device", usbDevice);
当我不再需要 UsbDevice 时,我将其从字典中删除。
_devices.Remove("Path of the device");
(为简单起见,我省略了所有检查设备是否存在)
当我删除 UsbDevice 时,我看到没有调用析构函数。这仅在应用程序关闭时完成。所以这意味着 UsbDevice 对象仍然存在于内存中的某个地方,对吧?我知道字典的“删除”方法不会从内存中删除 UsbDevice,因为字典不知道 UsbDevice 是否可以在代码中的其他地方使用(引用)。
如何摆脱与 UsbDevice 关联的所有内存?如果我不摆脱那个内存,那么添加/删除周期会因为所有未使用的 UsbDevices 而增加内存使用量,对吧?我怎样才能避免这种情况?
解决方案
- 最好让 CLR 决定何时释放内存
- 如果你现在真的需要释放你的内存——你可以使用 GC.Collect(); 这种方式会消耗资源,所以不建议手动使用。
- ~UsbDevice() 不是析构函数。这是终结者。当垃圾收集器发现这个对象可以被移除时——它会检查它是否有一个终结器。如果不是 - 它只是删除对象。如果是 - 那么对象将被放入特殊队列中,其中所有对象都具有终结器。在某个时间点将调用终结器,但对象仍位于内存中。当 GC 进行另一次迭代时——它会看到有一个已经执行的终结器——对象可以从内存中删除。这就是为什么使用终结器不是一个好习惯的原因。
- 如果您想释放一些非托管资源并且您确切知道何时应该发生这种情况 - 请查看 IDisposable。
推荐阅读
- node.js - 如何在谷歌操作和对话流中保存状态
- spring - Spring Data MongoDB 注解说明
- html - 服务的目的是什么?
- sas - 将 first.variable 和 last.variables 与累加器变量一起使用
- powerbi - power bi filter 按列过滤
- reactjs - 元素 ref 被指定为字符串(视图),但在 fork 和编辑 repo 时没有设置所有者
- javascript - WriteStream 不会写入所有数据
- php - 如何向 JSON Laravel 分页对象添加元素
- javascript - 将 onclicklistener 重新附加到按钮
- python-3.x - 如何根据具有多个 ID 的另一列从一列中选择特定值