public static void Dump() { TypeData.Start(); List <KeyValuePair <Type, Exception> > parseErrors = new List <KeyValuePair <Type, Exception> >(); string time = DateTime.Now.ToString().Replace('/', '_').Replace(':', '_'); string outPutFile = "E://LT_SnapShot/MonoHeap/" + time + ".txt"; using (var sw = new StreamWriter(outPutFile, false)) { sw.WriteLine("====================Mono Info====================="); long monoReserved = UnityEngine.Profiling.Profiler.GetMonoHeapSizeLong(); long monoUsed = UnityEngine.Profiling.Profiler.GetMonoUsedSizeLong(); sw.WriteLine($"monoReserved: {monoReserved / (1024*1024)}MB"); sw.WriteLine($"monoUsed: {monoUsed / (1024*1024)}MB"); sw.WriteLine("====================Heap Details====================="); foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies()) { foreach (var type in assembly.GetTypes()) { try { new StructOrClass(type, sw); } catch (Exception e) { parseErrors.Add(new KeyValuePair <Type, Exception>(type, e)); } } } } TypeData.Clear(); }
public static void Create() { TypeData.Start(); ThreadJobsPrinting = 0; ThreadJobsDone = 0; if (Directory.Exists("dump")) { Directory.Delete("dump", true); } Directory.CreateDirectory("dump"); Directory.CreateDirectory("dump/sobjects"); Directory.CreateDirectory("dump/uobjects"); Directory.CreateDirectory("dump/statics"); using (var logger = new StreamWriter("dump/memory.csv")) { Dictionary <Assembly, List <StructOrClass> > assemblyResults = new Dictionary <Assembly, List <StructOrClass> >(); Dictionary <Assembly, int> assemblySizes = new Dictionary <Assembly, int>(); List <KeyValuePair <Type, Exception> > parseErrors = new List <KeyValuePair <Type, Exception> >(); foreach (var assembly in AppDomain.CurrentDomain.GetAssemblies()) { string assemblyFolder; if (assembly.FullName.Contains("Assembly-CSharp")) { assemblyFolder = string.Format("dump/statics/{0}/", assembly.FullName.Replace("<", "(").Replace(">", ")").Replace(".", "_")); } else { assemblyFolder = "dump/statics/misc/"; } Directory.CreateDirectory(assemblyFolder); List <StructOrClass> types = new List <StructOrClass>(); foreach (var type in assembly.GetTypes()) { if (type.IsEnum || type.IsGenericType) { continue; } try { types.Add(new StructOrClass(type, assemblyFolder)); } catch (Exception e) { parseErrors.Add(new KeyValuePair <Type, Exception>(type, e)); } } assemblyResults[assembly] = types; } List <StructOrClass> unityComponents = new List <StructOrClass>(); foreach (var go in Resources.FindObjectsOfTypeAll <GameObject>()) { foreach (var component in go.GetComponents <Component>()) { if (component == null) { continue; } try { unityComponents.Add(new StructOrClass(component)); } catch (Exception e) { parseErrors.Add(new KeyValuePair <Type, Exception>(component.GetType(), e)); } } } List <StructOrClass> unityScriptableObjects = new List <StructOrClass>(); foreach (ScriptableObject scriptableObject in Resources.FindObjectsOfTypeAll <ScriptableObject>()) { if (scriptableObject == null) { continue; } try { unityScriptableObjects.Add(new StructOrClass(scriptableObject)); } catch (Exception e) { parseErrors.Add(new KeyValuePair <Type, Exception>(scriptableObject.GetType(), e)); } } foreach (var genericType in genericTypes.ToList()) { try { assemblyResults[genericType.Assembly].Add(new StructOrClass(genericType, "dump/statics/misc/")); } catch (Exception e) { parseErrors.Add(new KeyValuePair <Type, Exception>(genericType, e)); } } foreach (var pair in assemblyResults) { assemblySizes[pair.Key] = pair.Value.Sum(a => a.Size); pair.Value.Sort((a, b) => b.Size - a.Size); } TypeData.Clear(); var assemblySizesList = assemblySizes.ToList(); assemblySizesList.Sort((a, b) => (b.Value - a.Value)); unityComponents.Sort((a, b) => (b.Size - a.Size)); int unityComponentsSize = unityComponents.Sum(a => a.Size); bool printedUnityComponents = false; unityScriptableObjects.Sort((a, b) => (b.Size - a.Size)); int unityScriptableObjectsSize = unityScriptableObjects.Sum(a => a.Size); bool printedUnityScriptableObjects = false; //logger.WriteLine("Total tracked memory (including duplicates, so too high) = {0}", assemblySizesList.Sum(a => a.Value) + unityComponentsSize + unityScriptableObjectsSize); foreach (var pair in assemblySizesList) { var assembly = pair.Key; var size = pair.Value; if (!printedUnityComponents && size < unityComponentsSize) { printedUnityComponents = true; //logger.WriteLine("Unity components of total size: {0}", unityComponentsSize); foreach (var instance in unityComponents) { if (instance.Size >= TYPE_MIN_SIZE_TO_PRINT) { logger.WriteLine("\"{0}\",\"{1}\",{2},{3}", "Unity Components", instance.ParsedType.FullName, instance.InstanceID, instance.Size); } } } if (!printedUnityScriptableObjects && size < unityScriptableObjectsSize) { printedUnityScriptableObjects = true; //logger.WriteLine("Unity scriptableobjects of total size: {0}", unityScriptableObjectsSize); foreach (var instance in unityScriptableObjects) { if (instance.Size >= TYPE_MIN_SIZE_TO_PRINT) { logger.WriteLine("\"{0}\",\"{1}\",{2},{3}", "Unity ScriptableObjects", instance.ParsedType.FullName, instance.InstanceID, instance.Size); } } } //logger.WriteLine("Assembly: {0} of total size: {1}", assembly, size); foreach (var type in assemblyResults[assembly]) { if (type.Size >= TYPE_MIN_SIZE_TO_PRINT) { logger.WriteLine("\"{0}\",\"{1}\",,{2}", assembly, type.ParsedType.FullName, type.Size); } } } foreach (var error in parseErrors) { //logger.WriteLine(error); } } while (ThreadJobsDone < ThreadJobsPrinting) { System.Threading.Thread.Sleep(1); } }