Exemple #1
0
        // Process a trace and create a summary.
        static SnapshotSummary GetAllocSummary(ITraceProcessor trace)
        {
            var pendingSnapshotData = trace.UseHeapSnapshots();
            var pendingSymbols      = trace.UseSymbols();

            trace.Process();

            var snapshotData = pendingSnapshotData.Result;
            var symbols      = pendingSymbols.Result;

            symbols.LoadSymbolsAsync(new SymCachePath(@"c:\symcache")).GetAwaiter().GetResult();

            if (snapshotData.Snapshots.Count != 1)
            {
                Console.Error.WriteLine("Trace must contain exactly one heap snapshot - actually contained {0}.",
                                        snapshotData.Snapshots.Count);
                return(new SnapshotSummary(null, 0));
            }

            // Scan through all of the allocations and collect them by
            // SnapshotUniqueStackId (which corresponds to Stack Ref#),
            // accumulating the bytes allocated, allocation count, and the
            // stack.
            var allocsByStackId = new Dictionary <ulong, AllocDetails>();

            foreach (IHeapAllocation row in snapshotData.Snapshots[0].Allocations)
            {
                allocsByStackId.TryGetValue(row.SnapshotUniqueStackId, out AllocDetails value);
                value.Stack  = row.Stack;
                value.Size  += row.Size;
                value.Count += 1;
                allocsByStackId[row.SnapshotUniqueStackId] = value;
            }

            // Count how many allocations each stack frame is part of.
            // RtlThreadStart will presumably be near the top, along with
            // RtlpAllocateHeapInternal, but some clues may be found.
            var hotStackFrames = new Dictionary <string, long>();

            foreach (var data in allocsByStackId.Values)
            {
                foreach (var entry in data.Stack)
                {
                    var analyzerString = entry.GetAnalyzerString();
                    hotStackFrames.TryGetValue(analyzerString, out long count);
                    count += data.Count;
                    hotStackFrames[analyzerString] = count;
                }
            }

            var result = new SnapshotSummary(allocsByStackId, snapshotData.Snapshots[0].ProcessId);

            // Create a summary of the alloc counts and byte counts.
            var  totalAllocBytes = DataSize.Zero;
            long totalAllocCount = 0;

            foreach (var data in allocsByStackId.Values)
            {
                totalAllocBytes += data.Size;
                totalAllocCount += data.Count;
            }

            result.hotStackFrames_ = hotStackFrames;
            result.totalBytes_     = totalAllocBytes;
            result.allocCount_     = totalAllocCount;

            return(result);
        }