Beispiel #1
0
        public void AddObject(TypeInfo typeInfo, HeapObjectEvent heapObjectEvent)
        {
            if (heapObjectEvent.ObjectSize == 0)
            {
                // This means it's just reporting references
                // TODO: Validate if we need to handle it.
                return;
            }

            string typeName = typeInfo.Name;
            long   typeId   = typeInfo.TypeId;
            long   address  = heapObjectEvent.ObjectPointer;

            if (trackedTypeNames.Remove(typeName))
            {
                TrackedTypes.Add(typeName, typeId);
            }

            if (!Types.TryGetValue(typeId, out var heapTypeInfo))
            {
                Types[typeId] = heapTypeInfo = new HeapshotTypeInfo(typeInfo);
            }

            var heapObject = GetOrCreateObject(address, heapTypeInfo);

            Graph.AddVertex(heapObject);
            foreach (var reference in heapObjectEvent.References)
            {
                var referencedObject = GetOrCreateObject(reference.ObjectPointer, null);
                Graph.AddEdge(new Edge <HeapObject> (heapObject, referencedObject));
            }
        }
Beispiel #2
0
        string ReportPathsToRoots(Heapshot heapshot, HeapshotTypeInfo typeInfo, string iterationName, out int objectCount)
        {
            var    visitedRoots = new HashSet <HeapObject> ();
            string outputPath   = null;

            var rootTypeName = typeInfo.TypeInfo.Name;
            var objects      = typeInfo.Objects;

            objectCount = objects.Count;

            // Look for the first object that is definitely leaked.
            foreach (var obj in objects)
            {
                visitedRoots.Clear();
                bool isLeak = false;

                var paths = heapshot.Graph.GetPredecessors(obj, vertex => {
                    if (heapshot.Roots.TryGetValue(vertex.Address, out var heapRootRegisterEvent))
                    {
                        visitedRoots.Add(vertex);
                        isLeak |= IsActualLeakSource(heapRootRegisterEvent.Source);
                    }
                });

                if (outputPath == null && isLeak)
                {
                    var objectRetentionGraph = new AdjacencyGraph <HeapObject, SReversedEdge <HeapObject, Edge <HeapObject> > > ();

                    foreach (var root in visitedRoots)
                    {
                        if (paths.TryGetPath(root, out var edges))
                        {
                            objectRetentionGraph.AddVerticesAndEdgeRange(edges);
                        }
                    }
                    var graphviz = objectRetentionGraph.ToLeakGraphviz(heapshot);

                    var dotPath = Path.Combine(graphsDirectory, iterationName + "_" + rootTypeName + ".dot");
                    outputPath = graphviz.Generate(DotEngine.Instance, dotPath);
                }
                else
                {
                    objectCount--;
                }
            }

            // We have not found a definite leak if outputPath is null.
            return(outputPath);
        }
Beispiel #3
0
        HeapObject GetOrCreateObject(long address, HeapshotTypeInfo heapshotTypeInfo = null)
        {
            if (!Objects.TryGetValue(address, out var heapObject))
            {
                Objects[address] = heapObject = new HeapObject(address);
            }

            if (heapObject.TypeInfo == null && heapshotTypeInfo != null)
            {
                heapObject.TypeInfo = heapshotTypeInfo.TypeInfo;
                heapshotTypeInfo.Objects.Add(heapObject);
            }

            return(heapObject);
        }
Beispiel #4
0
 public bool TryGetHeapshotTypeInfo(long typeId, out HeapshotTypeInfo heapshotTypeInfo)
 => Types.TryGetValue(typeId, out heapshotTypeInfo);
Beispiel #5
0
        public bool TryGetHeapshotTypeInfo(string name, out HeapshotTypeInfo heapshotTypeInfo)
        {
            heapshotTypeInfo = null;

            return(TrackedTypes.TryGetValue(name, out var typeId) && TryGetHeapshotTypeInfo(typeId, out heapshotTypeInfo));
        }