Visual studio 是否可以实现GC.GetAliveInstancesOf<;T>;()(用于调试)?

Visual studio 是否可以实现GC.GetAliveInstancesOf<;T>;()(用于调试)?,visual-studio,debugging,windbg,garbage-collection,sos,Visual Studio,Debugging,Windbg,Garbage Collection,Sos,我知道这是,但我想提出一个不同的问题 是否有任何可以在Visual Studio调试监视窗口中评估的实现GC.GetAliveInstancesOf()的方法?Sasha Goldstein在中展示了一个解决方案,但它要求要查询的每个类都从特定的基类继承 我要强调的是,我只想在调试期间使用此方法,所以我不关心GC在运行时是否会更改对象在内存中的地址 一个想法可能是以某种方式利用!dumpheap–键入SOS的命令,然后做一些魔术来创建一个临时变量,并让它指向SOS打印的内存地址 有人有有效的解决

我知道这是,但我想提出一个不同的问题

是否有任何可以在Visual Studio调试监视窗口中评估的实现GC.GetAliveInstancesOf()的方法?Sasha Goldstein在中展示了一个解决方案,但它要求要查询的每个类都从特定的基类继承

我要强调的是,我只想在调试期间使用此方法,所以我不关心GC在运行时是否会更改对象在内存中的地址

一个想法可能是以某种方式利用!dumpheap–键入SOS的命令,然后做一些魔术来创建一个临时变量,并让它指向SOS打印的内存地址


有人有有效的解决方案吗?

没有什么比垃圾收集器不得不猜测某种用户代码可能对查找它不拥有的根感兴趣更能拖累垃圾收集器的了。让它尽可能快是至关重要的。就这一点而言,您能够看到引用内容的唯一方法是冻结可能正在从垃圾收集堆分配内存的所有线程


嗯,这是可能的,调试器就是这么做的。您已经知道Windbg的工作方式。然而,它并不是为跟踪托管对象而优化的工具。还有其他工具:内存分析器。有很多选择,不要试图建立自己的。从免费软件(和浪费时间的)CLR分析器,到第三方产品,如Ants和dotTrace以及其他许多产品。几百美元就可以解决你的问题,你一个人用更少的钱做得更好是不可能的。

这看起来很像是一个类似的问题。

我不想使用我自己的内存分析器。我想在托管堆上获取一个对象的地址(我可以使用windbg之类的工具获取该地址),然后在所有线程停止时,以某种方式在VisualStudio的Debug Watch窗口中获取该变量。从你的回答中我不明白你是否认为这是不可能的,以及为什么。拥有GC对象的地址是没有用的。垃圾收集器迟早会移动它(你不知道什么时候),你也不知道地址了。除非您有收集器更新的地址引用。当应用程序在断点处停止时,在计算某个表达式或类似的内容时,GC是否存在移动地址的风险?如果不是,那么我不在乎。。。假设此方法将从“调试监视”窗口调用,则下次我闯入调试器时将被迫重新计算方法调用。否,当调试器停止程序时,收集器无法运行。我想你会想做任何你做过的事情来获得地址,第一次还是第二次。没有解决这个问题,但是有如何从调试器的角度解决的背景知识:它是可以做到的。一个电话大概需要30秒,所以你不想打。基本上,它是通过调用相同的例程来完成的!dumpheap调用。是的,使用dumpheap获取对象地址,然后将其转换为托管对象引用,这不仅类似,而且完全是一个想法。你需要玩一些小把戏,以确保在此期间不会发生GC,但我找到了一种有效的方法。@AloisKraus非常有趣的东西,太棒了!然而,在WMemoryProfiler中,您似乎只尝试最小化GC发生的可能性,在100%的情况下,您并没有阻止它,所以您的API总是有可能引发灾难性的ExecutionEngineeException?这是准确的吗?是的,我很可能得到一个假的指针。但是,如果我是唯一分配线程,那么机会几乎为零,因为我实际上是在没有分配的情况下读取指针。在调试器中,我通过一个助手进程将指针字符串转换为long。然后我可以将长值直接读入一个数组并进行指针转换。