所有活动 ThreadLocal<T> 和 [ThreadStatic] 引用的列表

Posted

技术标签:

【中文标题】所有活动 ThreadLocal<T> 和 [ThreadStatic] 引用的列表【英文标题】:A list of all active ThreadLocal<T> and [ThreadStatic] references 【发布时间】:2016-10-30 11:17:23 【问题描述】:

如何获取当前保存在ThreadLocalThreadStatic 存储中的所有引用的列表?

即所有无法被垃圾回收的对象,因为某个线程在其thread-local storage 中持有对该对象的引用。

我可以在不知道它们的名称或类型的情况下使用反射来查找这些实例,或者至少是它们的总大小吗?

或者失败了,以某种方式在 Visual Studio 2010 中显示它们? (我正在寻找除了成熟的内存分析器之外的东西)

我的动机是这样的:我刚刚遇到了一个非常严重的内存泄漏,其中 ConcurrentBag 的内容被各种 ThreadPool 线程持有,即使最初的 ConcurrentBag 早已超出范围并被垃圾收集。虽然我已经解决了这个特殊的错误,但我想知道是否还有更多这样的错误潜伏在周围。

理想情况下,我希望通过某种方式在运行时定期记录线程本地存储所持有的对象数量及其大小。

【问题讨论】:

您可以使用 CLRMD(一个很酷的 Microsoft nuget 包)从进程中实时动态检索调试信息:github.com/Microsoft/clrmd/blob/master/Documentation/… 但是,通过我自己的测试,它似乎总是报告一个空的 ThreadStaticFields 集合。这可能是一个待解决的错误。它适用于标准类型的 ThreadLocal,而不是像 ThreadStatic 这样的特定属性 线程静态存储不是唯一的根存储位置。 .NET 中有 很多 种其他类型的根存储位置。 Hugo,我相信仍然没有办法做到这一点,除非您使用类似调试器的东西附加到您的流程中,在这种情况下,Simon 的建议对我来说看起来不错。原因在于,正如***.com/questions/28605611/… 上的 SO 所述,这是 VM/JIT 的深层实现细节。 【参考方案1】:

很遗憾,没有办法做到这一点。

您应该确保使用 IDisposable 实现进行清理,并在适当的情况下使用(一些 IDisposable)。

框架本身会为您计算引用,但没有 API 可将此信息公开给正在运行的代码。

【讨论】:

以上是关于所有活动 ThreadLocal<T> 和 [ThreadStatic] 引用的列表的主要内容,如果未能解决你的问题,请参考以下文章

ThreadLocal浅析

ThreadLocal

ThreadLocal随笔

NET问答: ThreadStatic 和 ThreadLocal<T; 哪一个更好 ?

手写自己的ThreadLocal(线程局部变量)

面试干货11——ThreadLocal原理