【问题标题】:how does a Dictionary find an object after a GC?Dictionary 如何在 GC 之后找到对象?
【发布时间】:2018-10-01 20:21:19
【问题描述】:

看这篇文章:references updated on GC,似乎堆可以在垃圾收集上被压缩,这意味着引用会改变。

现在,如果我将一个对象作为键放入字典中(假设该对象没有实现 GetHashCode/Equals),那么该引用将用于确定它在其内部哈希表中的位置。随后在 GC 上,如果引用更改,并且我想查找对象,C# 将如何找到它?

【问题讨论】:

  • 这最终涉及到运行时如何为引用类型生成一致的哈希码。见this。关键是哈希码不是字面意义上的地址,而是运行时内部同步块的一部分。
  • 不考虑哈希表或任何东西,如果T 是一个引用类型,那么任何T 类型的项目集合,包括List<T>,都将持有references i> 到它的每个项目。它的工作原理是实现细节。但可以肯定的是,如果垃圾收集器决定在某个时候压缩内存,在此过程中移动“堆”上的对象,它必须确保每个保留对这些对象的引用的人,包括 List<>Dictionary<,>,更新其引用(假设引用是某种类型的内存地址)。

标签: c# dictionary garbage-collection


【解决方案1】:

字典不使用对象在内存中的位置来记账——它使用哈希码。当对象在内存中移动时,对象的哈希码不会改变,即使它没有覆盖GetHashCode()。有关其工作原理的细节是非常多的实现细节,但您绝对可以依赖 GetHashCode() 在压缩前后返回相同的值(假设该方法没有以某种奇怪和可怕的方式被覆盖)。

虽然实现细节会随着时间而改变,this blog post 有一个有趣的(和最近的)描述。我相信这在 .NET Core(截至 2018 年 4 月)中仍然有效,基于 .NET Core CLR GitHub 存储库中的追逐代码 - 据我所知,this 是一个合理的起点。

【讨论】:

    猜你喜欢
    • 2021-02-28
    • 2018-03-21
    • 1970-01-01
    • 2019-01-29
    • 1970-01-01
    • 2015-08-24
    • 2020-12-14
    • 2010-10-17
    • 1970-01-01
    相关资源
    最近更新 更多