Closed jwdj closed 4 years ago
How do you find the static variabeles in ClrMD 2.0?
ClrHeap.EnumerateRoots(enumerateStatics: true)
Static variables aren't actually roots. In order to find all static variables, just enumerate all non-zero values of all reference type static fields of all types, in all app domains.
ClrRuntime runtime = ...;
foreach (ClrObject obj in
from module in runtime.EnumerateModules()
from map in module.EnumerateTypeDefToMethodTableMap()
let type = module.ResolveToken(map.Token)
where type != null // dotnet/roslyn#44913
from staticField in type.StaticFields // Thread-local static fields are no longer available.
where staticField.IsObjectReference
from domain in runtime.AppDomains
let obj = staticField.ReadObject(domain)
where obj.IsValid
select obj
)
{
Console.WriteLine(obj);
}
@NextTurn Thank you for your swift response and helpful example. I don't mind v2 is more elaborate while v1 did more under the hood. It helps in understanding the way managed memory (and static vars in particular) is structured. Closing this issue.
@jwdj Please feel free to open more issues to ask questions if you run into trouble in the future.
FYI, I've moved a lot of things that were super slow or in some way hacky out of the library. I haven't decided whether I will add them to the "Utilities" library or not, but I just haven't had time to make the decision and then implement it.
Enumerating all types in all modules is one of those things (use EnumerateTypeDefToMethodTableMap
instead). Static variable "roots" are another. Static variables are always rooted by a strong GC handle, but there's not a quick way to enumerate all static variables in the process to map onto "roots". Since it takes SO long to walk every MT in the process I removed it from the roots enumeration.
I need to put these things in the FAQ but I came right down to the wire fixing issues and I didn't want to push back 2.0 for another week.
+1 to need of finding static "roots". For the moment I'll go with @NextTurn's solution I suppose.
FYI, I've moved a lot of things that were super slow or in some way hacky out of the library. I haven't decided whether I will add them to the "Utilities" library or not, but I just haven't had time to make the decision and then implement it.
Maybe extensions library? Adding ClrHeap.EnumerateStaticObjects
extension method? Could be a separate nuget
@leculver, @NextTurn First of all, congratulations on releasing ClrMD 2! A lot of effort went into it.
With ClrMD 1.1 there used to be much more roots. You could see the static variables. How do you find the static variabeles in ClrMD 2.0?
I think it is more informative to know which static variable is holding on to an object than to know it is a pinned handle.