예제 #1
0
        public static void RegisterItem([NotNull] CrawlItem item)
        {
            if (!SnapshotHistory.IsNew(item.Object))
            {
                return;
            }

            var stats = DemandTypeStats(item.Object.GetType());

            stats.Count++;
            stats.SelfSize  += item.SelfSize;
            stats.TotalSize += item.TotalSize;

            var unityObject = item.Object as UnityEngine.Object;

            if (unityObject != null)
            {
                stats.NativeSize += Profiler.GetRuntimeMemorySizeLong(unityObject);
            }

            if (stats.tracked)
            {
                stats.DemandInstanceStats(item.Object).Size = item.TotalSize;
            }
        }
예제 #2
0
        private void CleanupUnchanged()
        {
            if (Children != null)
            {
                foreach (var c in Children)
                {
                    c.CleanupUnchanged();
                }

                Children.RemoveAll(c => !c.SubtreeUpdated);
                SubtreeUpdated = Children.Count > 0;
            }

            SubtreeUpdated |= SnapshotHistory.IsNew(Object);
        }
예제 #3
0
        public static void RegisterInstance([NotNull] CrawlItem parent, [NotNull] string name, [NotNull] object instance)
        {
            if (!SnapshotHistory.IsNew(instance))
            {
                return;
            }

            var stats = DemandTypeStats(instance.GetType());

            if (!stats.tracked)
            {
                return;
            }

            var instanceStats = stats.DemandInstanceStats(instance);
            var rootPath      = parent.GetRootPath() + "." + name;

            instanceStats.RootPaths.Add(rootPath);
        }
예제 #4
0
        private long CalculateSelfManagedSize()
        {
            if (!SnapshotHistory.IsNew(Object))
            {
                return(0);
            }

            string str = Object as string;

            if (str != null)
            {
                // string needs special handling
                int strSize = 3 * IntPtr.Size + 2;
                strSize += str.Length * sizeof(char);
                int pad = strSize % IntPtr.Size;
                if (pad != 0)
                {
                    strSize += IntPtr.Size - pad;
                }
                return(strSize);
            }


            if (Object.GetType().IsArray)
            {
                var elementType = Object.GetType().GetElementType();
                if (elementType != null && (elementType.IsValueType || elementType.IsPrimitive || elementType.IsEnum))
                {
                    // no overhead for array
                    return(0);
                }
                else
                {
                    int arraySize = GetTotalArrayLength((Array)Object);
                    return(IntPtr.Size * arraySize);
                }
            }

            return(TypeData.Get(Object.GetType()).Size);
        }
        /// <summary>
        /// Let The Crawling Begin!
        /// </summary>
        public void Start()
        {
            // traverse order:
            // 1. used definded roots (without Unity objects)
            // 2. static fields (without Unity objects)
            // 3. game objects in scene hierarchy (seperate view)
            // 4. ScriptableObjects (with all referenced Unity objects)
            // 5. Prefabs (with all referenced Unity objects)
            // 6. all remaining Unity objects (ScriptableObject and other stuff)
            // user can add custom groups using AddRootsGroup and AddUnityRootsGroup
            try
            {
                if (!DifferentialMode)
                {
                    SnapshotHistory.Clear();
                }

                TypeData.Start();
                TypeStats.Init(trackedTypes);

                outputDir = "snapshot-" + DateTime.Now.ToString("s").Replace(":", "_");
                if (DifferentialMode && SnapshotHistory.IsPresent())
                {
                    outputDir += "-diff";
                }
                outputDir += "/";

                Directory.CreateDirectory(outputDir);

                using (var log = new StreamWriter(outputDir + "log.txt"))
                {
                    log.AutoFlush = true;

                    GC.Collect();
                    GC.Collect();
                    log.WriteLine("Mono Size Min: " + sizeFormat.Format(Profiler.GetMonoUsedSizeLong()));
                    log.WriteLine("Mono Size Max: " + sizeFormat.Format(Profiler.GetMonoHeapSizeLong()));
                    log.WriteLine("Total Allocated: " + sizeFormat.Format(Profiler.GetTotalAllocatedMemoryLong()));
                    log.WriteLine("Total Reserved: " + sizeFormat.Format(Profiler.GetTotalReservedMemoryLong()));
                    log.WriteLine();

                    // now add predefined crawl settings and sort by priority
                    // all user crawl settings were added before so they will precede predefined ones with same priority
                    crawlOrder.Add(UserRootsSettings);
                    crawlOrder.Add(StaticFieldsSettings);
                    crawlOrder.Add(HierarchySettings);
                    crawlOrder.Add(ScriptableObjectsSettings);
                    crawlOrder.Add(PrefabsSettings);
                    crawlOrder.Add(UnityObjectsSettings);
                    crawlOrder.RemoveAll(cs => !cs.Enabled);
                    crawlOrder.Sort(CrawlSettings.PriorityComparer);

#if UNITY_EDITOR
                    EditorUtility.DisplayProgressBar("Heap Snapshot", "Collecting Unity Objects...", 0f);
#endif
                    unityObjects.Clear();
                    var unityObjectsList = Resources.FindObjectsOfTypeAll <Object>();
                    foreach (var o in unityObjectsList)
                    {
                        unityObjects.Add(o);
                    }

                    long  totalSize    = 0;
                    float progressStep = 0.8f / crawlOrder.Count;
                    for (var i = 0; i < crawlOrder.Count; i++)
                    {
                        float startProgress = 0.1f + progressStep * i;
                        float endProgress   = 0.1f + progressStep * (i + 1);
                        var   crawlSettings = crawlOrder[i];

                        DisplayCollectProgressBar(crawlSettings, startProgress);

                        crawlSettings.RootsCollector();

                        int  displayIndex = i + 1;
                        long rootsSize    = CrawlRoots(crawlSettings, displayIndex, startProgress, endProgress);

                        log.WriteLine($"{crawlSettings.Caption} size: " + sizeFormat.Format(rootsSize));
                        totalSize += rootsSize;
                    }

                    log.WriteLine("Total size: " + sizeFormat.Format(totalSize));
                }

#if UNITY_EDITOR
                EditorUtility.DisplayProgressBar("Heap Snapshot", "Printing Type Statistics...", 0.95f);
#endif
                PrintTypeStats(TypeSizeMode.Self, "types-self.txt");
                PrintTypeStats(TypeSizeMode.Total, "types-total.txt");
                PrintTypeStats(TypeSizeMode.Native, "types-native.txt");

#if UNITY_EDITOR
                EditorUtility.DisplayProgressBar("Heap Snapshot", "Printing Instance Statistics...", 0.95f);
#endif
                PrintInstanceStats();

                if (DifferentialMode)
                {
                    SnapshotHistory.Store(visitedObjects);
                }

                Debug.Log("Heap snapshot created: " + outputDir);
            }
            finally
            {
#if UNITY_EDITOR
                EditorUtility.ClearProgressBar();
#endif
            }
        }
예제 #6
0
        public void CleanupInternal(CrawlSettings crawlSettings)
        {
            if (!crawlSettings.PrintChildren)
            {
                Children = null;
            }

            if (crawlSettings.MaxDepth > 0 && depth >= crawlSettings.MaxDepth)
            {
                Children = null;
            }

            if (SnapshotHistory.IsPresent() && SnapshotHistory.IsNew(Object))
            {
                Name = Name + " (new)";
            }

            // check for destroyed objects
            var unityObject = Object as Object;

            if (!ReferenceEquals(unityObject, null) && !unityObject)
            {
                const string destroyedObjectString = "(destroyed Unity Object)";
                if (string.IsNullOrWhiteSpace(Name))
                {
                    Name = destroyedObjectString;
                }
                else
                {
                    Name = Name + " " + destroyedObjectString;
                }

                Children = null;
            }

            if (Children == null)
            {
                return;
            }

            if (crawlSettings.PrintOnlyGameObjects)
            {
                Children.RemoveAll(c => !(c.Object is GameObject));
            }

            int fullChildrenCount = Children.Count;

            if (crawlSettings.MinItemSize > 0)
            {
                Children.RemoveAll(c => c.TotalSize < crawlSettings.MinItemSize);
            }
            if (crawlSettings.MaxChildren > 0 && Children.Count > crawlSettings.MaxChildren)
            {
                Children.RemoveRange(crawlSettings.MaxChildren, Children.Count - crawlSettings.MaxChildren);
            }

            if (Children.Count < fullChildrenCount)
            {
                childrenFiltered = true;
            }

            depth++;
            foreach (var child in Children)
            {
                child.CleanupInternal(crawlSettings);
            }
            depth--;
        }