/// <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 } }
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--; }