public void Print([NotNull] StreamWriter w, SizeFormat sizeFormat) { for (int i = 0; i < depth; ++i) { w.Write(" "); } if (!string.IsNullOrWhiteSpace(Name)) { w.Write(Name); w.Write(" "); } w.Write("["); var uo = Object as Object; if (uo != null) { w.Write(uo.name); w.Write(": "); w.Write(Object.GetType().GetDisplayName()); w.Write(" ("); w.Write(uo.GetInstanceID()); w.Write(")"); } else { w.Write(Object.GetType().GetDisplayName()); } w.Write("]"); w.Write(" "); w.Write(sizeFormat.Format(TotalSize)); w.WriteLine(); if (Children != null) { depth++; foreach (var child in Children) { child.Print(w, sizeFormat); } if (childrenFiltered && Children.Count > 0) { for (int j = 0; j < depth; ++j) { w.Write(" "); } w.WriteLine("..."); } depth--; } }
/// <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 } }
/// <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. all remaining Unity objects (ScriptableObject and other stuff) try { TypeData.Start(); TypeStats.Init(trackedTypes); outputDir = "snapshot-" + DateTime.Now.ToString("s").Replace(":", "_") + '/'; Directory.CreateDirectory(outputDir); using (var log = new StreamWriter(outputDir + "log.txt")) { log.AutoFlush = true; 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(); #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); } int customRootsSize = CrawlCustomRoots(); if (customRootsSize > 0) { log.WriteLine("Custom roots size: " + sizeFormat.Format(customRootsSize)); } int staticRootsSize = CrawlStaticFields(); if (staticRootsSize > 0) { log.WriteLine("Static fields size: " + sizeFormat.Format(staticRootsSize)); } int hierarchySize = CrawlHierarchy(); if (hierarchySize > 0) { log.WriteLine("Heirarchy size: " + sizeFormat.Format(hierarchySize)); } int unityObjectsSize = CrawlUnityObjects(); if (unityObjectsSize > 0) { log.WriteLine("Unity objects size: " + sizeFormat.Format(unityObjectsSize)); } int totalSize = customRootsSize + staticRootsSize + hierarchySize + unityObjectsSize; 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(); Debug.Log("Heap snapshot created: " + outputDir); } finally { #if UNITY_EDITOR EditorUtility.ClearProgressBar(); #endif } }