示例#1
0
        protected IEnumerator <object> CaptureSnapshotTask(string targetFilename)
        {
            var now = DateTime.Now;

            var mem = new MemoryStatistics(Process);

            var psi = new ProcessStartInfo(
                Settings.UmdhPath, String.Format(
                    "-g -p:{0} -f:\"{1}\"", Process.Id, targetFilename
                    )
                );

            TemporaryFiles.Add(targetFilename);

            using (Activities.AddItem("Capturing heap snapshot"))
                yield return(Program.RunProcess(psi));

            yield return(Future.RunInThread(
                             () => File.AppendAllText(targetFilename, mem.GetFileText())
                             ));

            var fText = Future.RunInThread(
                () => File.ReadAllText(targetFilename)
                );

            yield return(fText);

            var text = fText.Result;

            fText = null;

            yield return(FinishLoadingSnapshot(Snapshots.Count, now, targetFilename, text));
        }
示例#2
0
        static void Serialize(ref SerializationContext context, ref MemoryStatistics input)
        {
            var cv = Mapper <MemoryStatistics> .GetColumnValues(input);

            var bw = new BinaryWriter(context.Stream, Encoding.UTF8);

            bw.Write(cv.Length);
            for (int i = 0; i < cv.Length; i++)
            {
                bw.Write((long)cv[i]);
            }
            bw.Flush();
        }
示例#3
0
        public HeapSnapshotInfo(
            int index, DateTime timestamp, string filename,
            MemoryStatistics memory, HeapSnapshot snapshot
            ) : base(
                (from heap in snapshot.Heaps select(from alloc in heap.Allocations select(long) alloc.Size).Sum()).Sum(),
                (from heap in snapshot.Heaps select(from alloc in heap.Allocations select(long) alloc.Overhead).Sum()).Sum(),
                (from heap in snapshot.Heaps select(from alloc in heap.Allocations select(long)(alloc.Size + alloc.Overhead)).Sum()).Sum(),
                (from heap in snapshot.Heaps select heap.Allocations.Count).Sum()
                )
        {
            Index      = index;
            Timestamp  = timestamp;
            Filename   = filename;
            Memory     = memory;
            _StrongRef = snapshot;

            HeapFragmentation        = (from heap in snapshot.Heaps select heap.Info.EmptySpans).Sum() / (float)Math.Max(1, (from heap in snapshot.Heaps select heap.Allocations.Count).Sum());
            LargestFreeHeapBlock     = (from heap in snapshot.Heaps select heap.Info.LargestFreeSpan).Max();
            LargestOccupiedHeapBlock = (from heap in snapshot.Heaps select heap.Info.LargestOccupiedSpan).Max();
            AverageFreeBlockSize     = (long)(from heap in snapshot.Heaps select(heap.Info.EstimatedFree) / Math.Max(heap.Info.EmptySpans, 1)).Average();
            AverageOccupiedBlockSize = (long)(from heap in snapshot.Heaps select(heap.Info.TotalOverhead + heap.Info.TotalRequested) / Math.Max(heap.Info.OccupiedSpans, 1)).Average();
        }
示例#4
0
        protected HeapSnapshotInfo(
            int index, DateTime timestamp, string filename, MemoryStatistics memory,
            float heapFragmentation, long largestFreeHeapBlock, long largestOccupiedHeapBlock,
            long averageFreeBlockSize, long averageOccupiedBlockSize,
            long bytesAllocated, long bytesOverhead, long bytesTotal,
            int allocationCount
            ) : base(
                bytesAllocated, bytesOverhead, bytesTotal, allocationCount
                )
        {
            Index     = index;
            Timestamp = timestamp;
            Filename  = filename;
            Memory    = memory;

            HeapFragmentation        = heapFragmentation;
            LargestFreeHeapBlock     = largestFreeHeapBlock;
            LargestOccupiedHeapBlock = largestOccupiedHeapBlock;
            AverageFreeBlockSize     = averageFreeBlockSize;
            AverageOccupiedBlockSize = averageOccupiedBlockSize;

            _StrongRef = null;
            _WeakRef   = null;
        }
示例#5
0
        public HeapSnapshot(int index, DateTime when, string filename, string text)
        {
            MemoryStatistics memory = new MemoryStatistics();
            bool             scanningForStart = true, scanningForMemory = false;
            Heap             scanningHeap = null;

            var regexes = new Regexes();

            int groupModule        = regexes.SnapshotModule.GroupNumberFromName("module");
            int groupModuleOffset  = regexes.SnapshotModule.GroupNumberFromName("offset");
            int groupModuleSize    = regexes.SnapshotModule.GroupNumberFromName("size");
            int groupHeaderId      = regexes.HeapHeader.GroupNumberFromName("id");
            int groupAllocOffset   = regexes.Allocation.GroupNumberFromName("offset");
            int groupAllocSize     = regexes.Allocation.GroupNumberFromName("size");
            int groupAllocOverhead = regexes.Allocation.GroupNumberFromName("overhead");
            int groupAllocId       = regexes.Allocation.GroupNumberFromName("id");

            Match m;

            // Instead of allocating a tiny new UInt32[] for every traceback we read in,
            //  we store groups of tracebacks into fixed-size buffers so that the GC has
            //  less work to do when performing collections. Tracebacks are read-only after
            //  being constructed, and all the tracebacks from a snapshot have the same
            //  lifetime, so this works out well.
            var frameBuffer      = new UInt32[FrameBufferSize];
            int frameBufferCount = 0;

            var lr = new LineReader(text);

            LineReader.Line line;

            while (lr.ReadLine(out line))
            {
                if (scanningHeap != null)
                {
                    if (line.StartsWith("*-") && line.Contains("End of data for heap"))
                    {
                        scanningHeap.Allocations.TrimExcess();
                        scanningHeap = null;
                    }
                    else if (regexes.Allocation.TryMatch(ref line, out m))
                    {
                        var       tracebackId = UInt32.Parse(m.Groups[groupAllocId].Value, NumberStyles.HexNumber);
                        Traceback traceback;

                        if (!Tracebacks.TryGetValue(tracebackId, out traceback))
                        {
                            // If the frame buffer could fill up while we're building our traceback,
                            //  let's allocate a new one.
                            if (frameBufferCount >= frameBuffer.Length - MaxTracebackLength)
                            {
                                frameBuffer      = new UInt32[frameBuffer.Length];
                                frameBufferCount = 0;
                            }

                            int firstFrame = frameBufferCount;

                            // This is only valid if every allocation is followed by an empty line
                            while (lr.ReadLine(out line))
                            {
                                if (line.StartsWith("\t"))
                                {
                                    frameBuffer[frameBufferCount++] = UInt32.Parse(
                                        line.ToString(), NumberStyles.HexNumber | NumberStyles.AllowLeadingWhite
                                        );
                                }
                                else
                                {
                                    lr.Rewind(ref line);
                                    break;
                                }
                            }

                            Tracebacks.Add(traceback = new Traceback(
                                               tracebackId, new ArraySegment <UInt32>(frameBuffer, firstFrame, frameBufferCount - firstFrame)
                                               ));
                        }

                        scanningHeap.Allocations.Add(new Allocation(
                                                         UInt32.Parse(m.Groups[groupAllocOffset].Value, NumberStyles.HexNumber),
                                                         UInt32.Parse(m.Groups[groupAllocSize].Value, NumberStyles.HexNumber),
                                                         UInt32.Parse(m.Groups[groupAllocOverhead].Value, NumberStyles.HexNumber),
                                                         traceback.ID
                                                         ));
                    }
                }
                else if (scanningForMemory)
                {
                    if (regexes.HeapHeader.TryMatch(ref line, out m))
                    {
                        scanningHeap = new Heap(index, UInt32.Parse(m.Groups[groupHeaderId].Value, NumberStyles.HexNumber));
                        Heaps.Add(scanningHeap);
                    }
                    else if (line.StartsWith("// Memory="))
                    {
                        memory            = new MemoryStatistics(line.ToString());
                        scanningForMemory = false;
                        break;
                    }
                    else
                    {
                        continue;
                    }
                }
                else if (scanningForStart)
                {
                    if (line.Contains("Loaded modules"))
                    {
                        scanningForStart = false;
                    }
                    else if (line.Contains("Start of data for heap"))
                    {
                        break;
                    }
                    else
                    {
                        continue;
                    }
                }
                else
                {
                    if (!regexes.SnapshotModule.TryMatch(ref line, out m))
                    {
                        if (line.Contains("Process modules enumerated"))
                        {
                            scanningForMemory = true;
                        }
                        else
                        {
                            continue;
                        }
                    }
                    else
                    {
                        var modulePath = Path.GetFullPath(m.Groups[groupModule].Value).ToLowerInvariant();
                        Modules.Add(new Module(
                                        modulePath,
                                        UInt32.Parse(m.Groups[groupModuleOffset].Value, System.Globalization.NumberStyles.HexNumber),
                                        UInt32.Parse(m.Groups[groupModuleSize].Value, System.Globalization.NumberStyles.HexNumber)
                                        ));
                    }
                }
            }

            foreach (var heap in Heaps)
            {
                heap.Allocations.Sort(
                    (lhs, rhs) => lhs.Address.CompareTo(rhs.Address)
                    );
                heap.ComputeStatistics();
            }

            Info = new HeapSnapshotInfo(index, when, filename, memory, this);
        }
示例#6
0
        static void Deserialize(ref DeserializationContext context, out MemoryStatistics output)
        {
            var br = new BinaryReader(context.Stream, Encoding.UTF8);

            output = new MemoryStatistics(br);
        }