Projekt MemoryVisualizera toczy się w kilku wątkach, ale jak na razie dość mało poświęciłem jednemu z najważniejszych - analizy pamięci. Planuję bardziej rozbudowany post o tym jak można się do pamięci dobrać i co tak naprawdę siedzi pod spodem. Na razie jednak jako "zajawkę" przedstawię sposób, którym się będę przez dłuższy czas posługiwał. A chodzi o świetną bibliotekę ClrMd, która to jako dostępna na Nuget, oferuje interfejs .NETowy do analizy pamięci. Szukając go w Visual Studio pamiętajmy zaznaczyć opcję "Include prerelease" ponieważ jest to wciąż biblioteka w wersji rozwojowej.

Jak to wygląda w praktyce? Chyba zamiast strzępić język, najprościej przemówi kod. Co więcej, ponieważ .NET fajny jest, bibliotekę tą bez problemów mogę użyć od razu w F#, bez kombinowania:
use target = DataTarget.LoadCrashDump(@"..\..\..\..\data\ConsoleDump.exe.dmp")
for version in target.ClrVersions do
let dacInfo = version.DacInfo
let runtime = version.CreateRuntime()
let heap = runtime.GetHeap()
for objectAddr in heap.EnumerateObjectAddresses() do
let objType = heap.GetObjectType(objectAddr)
let objSize = objType.GetSize(objectAddr)
let value = if objType.Name = "System.String" then objType.GetValue(objectAddr) :?> string else ""
let heapObject = new HeapObject(Address = objectAddr,
TypeName = objType.Name,
Size = objSize,
Value = value)
heapObjects.Add(heapObject)
Jak widać posługiwanie się ClrMd jest banalnie proste. Powyższy kod wypełnia listę heapObjects obiektami HeapObject - mniejsza o ich definicje. Za pomocą ClrMd można też śledzić referencje pomiędzy obiektami, co posłuży mi do zbudowania grafu obiektów. Można wylistować regiony w pamięci, "kolejkę finalizacji". Możemy podejrzeć wszystkie wątki, ich stack trace i obiekty znajdujące się na stosie. Ogólnie możemy naprawdę wiele i stopniowo będę to opisywał. Tymczasem obecna wersja MemoryVisualizera posługując się powyższym kodem wypluwa dane prostego memory dumpa:

Jest moc! Kolejne przygody z ClrMd w kolejnych wpisach, bo to jest dla nas zdecydowanie dłuższa przygoda.