コード例 #1
0
ファイル: HeapSnapshot.cs プロジェクト: puppytodd/heap-shot
        // Returns a list of paths. Each path is a sequence of objects, starting
        // on an object of type 'type' and ending on a root.
        public PathTree GetRoots(IProgressListener listener, int type)
        {
            RootInfo rootInfo = new RootInfo();
            PathTree pathTree = new PathTree(this);

            foreach (int obj in GetObjectsByType(type))
            {
                rootInfo.BaseObjects [obj] = obj;
            }

            int nc = 0;

            foreach (int obj in GetObjectsByType(type))
            {
                if (listener.Cancelled)
                {
                    return(null);
                }

                rootInfo.nc = 0;

                FindRoot(rootInfo, pathTree, obj);

                // Register partial paths to the root, to avoid having to
                // recalculate them again

//				if (nc % 100 == 0)
//					Console.WriteLine ("NC: " + nc + " " + rootInfo.Roots.Count);

                pathTree.AddBaseObject(obj);
                foreach (KeyValuePair <int, int[]> e in rootInfo.Roots)
                {
                    pathTree.AddPath(e.Value);
                }
                rootInfo.Visited.Clear();
                rootInfo.Roots.Clear();
                nc++;

                double newp = (double)nc / (double)rootInfo.BaseObjects.Count;
                listener.ReportProgress("Looking for roots", newp);
            }

            pathTree.Flush();
            return(pathTree);
        }
コード例 #2
0
ファイル: HeapSnapshot.cs プロジェクト: puppytodd/heap-shot
        void FindTreeRoot(List <int> path, Dictionary <int, int[]> roots, PathTree pathTree, int node)
        {
            int obj = pathTree.GetNodeObject(node);

            path.Add(obj);

            bool hasRef = false;

            foreach (int cnode in pathTree.GetChildNodes(node))
            {
                FindTreeRoot(path, roots, pathTree, cnode);
                hasRef = true;
            }

            if (!hasRef)
            {
                // A root
                RegisterPath(roots, path, obj);
            }

            path.RemoveAt(path.Count - 1);
        }
コード例 #3
0
ファイル: HeapSnapshot.cs プロジェクト: puppytodd/heap-shot
        // It returns -2 of obj is a dead end
        // Returns n >= 0, if all paths starting at 'obj' end in objects already
        // visited. 'n' is the index of a node in rootInfo.Path, which is the closest
        // visited node found
        // Returns -1 otherwise.
        // This return value is used to detect dead ends.

        int FindRoot(RootInfo rootInfo, PathTree pathTree, int obj)
        {
            if (rootInfo.DeadEnds.ContainsKey(obj))
            {
                return(-2);
            }

            int curval;

            if (rootInfo.Visited.TryGetValue(obj, out curval))
            {
                // The object has already been visited
                if (rootInfo.Path.Count >= curval)
                {
                    return(rootInfo.Path.IndexOf(obj));
                }
            }
            rootInfo.Visited [obj] = rootInfo.Path.Count;

            int treePos = pathTree.GetObjectNode(obj);

            if (treePos != -1)
            {
                // If this object already has partial paths to roots,
                // reuse them.
                FindTreeRoot(rootInfo.Path, rootInfo.Roots, pathTree, treePos);
                return(-1);
            }

            rootInfo.Path.Add(obj);

            bool hasrefs    = false;
            int  findresult = int.MaxValue;

            foreach (int oref in GetReferencers(obj))
            {
                hasrefs = true;
                if (!rootInfo.BaseObjects.ContainsKey(oref))
                {
                    int fr = FindRoot(rootInfo, pathTree, oref);
                    if (fr != -2 && fr < findresult)
                    {
                        findresult = fr;
                    }
                }
            }

            if (!hasrefs)
            {
                // A root
                rootInfo.Visited.Remove(obj);
                RegisterPath(rootInfo.Roots, rootInfo.Path, obj);
                findresult = -1;
            }

            rootInfo.Path.RemoveAt(rootInfo.Path.Count - 1);

            // If all children paths end in nodes already visited, it means that it is a dead end.
            if (findresult >= rootInfo.Path.Count)
            {
                rootInfo.DeadEnds [obj] = obj;
//				Console.WriteLine ("de: " + findresult);
            }

            return(findresult);
        }