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