Example #1
0
 private void DrawSpecificTexture2D(NativeUnityEngineObject nativeObject)
 {
     if (nativeObject.className != "Texture2D")
     {
         _textureObject = null;
         return;
     }
     EditorGUILayout.HelpBox("Watching Texture Detail Data is only for Editor.", MessageType.Warning, true);
     if (_prevInstance != nativeObject.instanceID)
     {
         _textureObject = EditorUtility.InstanceIDToObject(nativeObject.instanceID) as Texture2D;
         _prevInstance  = nativeObject.instanceID;
     }
     if (_textureObject != null)
     {
         EditorGUILayout.LabelField("textureInfo: " + _textureObject.width + "x" + _textureObject.height + " " + _textureObject.format);
         EditorGUILayout.ObjectField(_textureObject, typeof(Texture2D));
         _textureSize = EditorGUILayout.Slider(_textureSize, 100.0f, 1024.0f);
         GUILayout.Label(_textureObject, GUILayout.Width(_textureSize), GUILayout.Height(_textureSize * _textureObject.height / _textureObject.width));
     }
     else
     {
         EditorGUILayout.LabelField("Can't instance texture,maybe it was alreadt released.");
     }
 }
Example #2
0
 private void DrawSpecificTexture2D(NativeUnityEngineObject nativeObject)
 {
     if (nativeObject.className != "Texture2D")
     {
         _textureObject = null;
         return;
     }
     EditorGUILayout.HelpBox("Previewing Texture2D only works correctly when profiling inside the editor.", MessageType.Warning, true);
     if (_prevInstance != nativeObject.instanceID)
     {
         // Attempt to match the texture to one in editor
         _textureObject = GetTexture(nativeObject);
         _prevInstance  = nativeObject.instanceID;
     }
     if (_textureObject != null)
     {
         EditorGUILayout.LabelField("textureInfo: " + _textureObject.width + "x" + _textureObject.height + " " + _textureObject.format);
         EditorGUILayout.ObjectField(_textureObject, typeof(Texture2D), false);
         _textureSize = EditorGUILayout.Slider(_textureSize, 100.0f, 1024.0f);
         GUILayout.Label(_textureObject, GUILayout.Width(_textureSize), GUILayout.Height(_textureSize * _textureObject.height / _textureObject.width));
     }
     else
     {
         EditorGUILayout.LabelField("Can't instance the texture, maybe it was already released.");
     }
 }
Example #3
0
        public static CrawledMemorySnapshot Unpack(PackedCrawlerData packedCrawlerData)
        {
            var packedSnapshot = packedCrawlerData.packedMemorySnapshot;

            var result = new CrawledMemorySnapshot
            {
                //nativeObjects = packedSnapshot.nativeObjects.Select(packedNativeUnityEngineObject => UnpackNativeUnityEngineObject(packedSnapshot, packedNativeUnityEngineObject)).ToArray(),
                managedObjects            = packedCrawlerData.managedObjects.Select(pm => UnpackManagedObject(packedSnapshot, pm)).ToArray(),
                gcHandles                 = packedSnapshot.gcHandles.Select(pgc => UnpackGCHandle(packedSnapshot)).ToArray(),
                staticFields              = packedSnapshot.typeDescriptions.Where(t => t.staticFieldBytes != null & t.staticFieldBytes.Length > 0).Select(t => UnpackStaticFields(t)).ToArray(),
                typeDescriptions          = packedSnapshot.typeDescriptions,
                managedHeap               = packedSnapshot.managedHeapSections,
                nativeTypes               = packedSnapshot.nativeTypes,
                virtualMachineInformation = packedSnapshot.virtualMachineInformation
            };

            PackedNativeUnityEngineObject[] objects   = packedSnapshot.nativeObjects;
            List <NativeUnityEngineObject>  temp_list = new List <NativeUnityEngineObject>();

            for (int i = 0; i < objects.Length; i++)
            {
                NativeUnityEngineObject nativeObj = UnpackNativeUnityEngineObjectIgnoreUnityBuiltin(packedSnapshot, objects[i]);

                if (nativeObj == null)
                {
                    continue;
                }
                temp_list.Add(nativeObj);
            }
            result.nativeObjects = temp_list.ToArray();

            var combined = new ThingInMemory[0].Concat(result.gcHandles).Concat(result.nativeObjects).Concat(result.staticFields).Concat(result.managedObjects).ToArray();

            result.allObjects = combined;

            var referencesLists   = MakeTempLists(combined);
            var referencedByLists = MakeTempLists(combined);

            foreach (var connection in packedCrawlerData.connections)
            {
                if (connection.@from >= referencesLists.Length || connection.to >= combined.Length)
                {
                    continue;
                }

                referencesLists[connection.@from].Add(combined[connection.to]);
                referencedByLists[connection.to].Add(combined[connection.@from]);
            }

            for (var i = 0; i != combined.Length; i++)
            {
                combined[i].references   = referencesLists[i].ToArray();
                combined[i].referencedBy = referencedByLists[i].ToArray();
            }

            return(result);
        }
Example #4
0
 private bool CompareNativeUnityEngineObject(NativeUnityEngineObject obj1, NativeUnityEngineObject obj2)
 {
     return(((obj1.instanceID == obj2.instanceID && this._needCompareInstanceID) || !this._needCompareInstanceID) &&
            obj1.size == obj2.size &&
            obj1.classID == obj2.classID &&
            obj1.className == obj2.className &&
            obj1.name == obj2.name &&
            obj1.isPersistent == obj2.isPersistent &&
            obj1.isDontDestroyOnLoad == obj2.isDontDestroyOnLoad &&
            obj1.isManager == obj2.isManager &&
            obj1.hideFlags == obj2.hideFlags);
 }
Example #5
0
 private void DrawNativeObject(NativeUnityEngineObject nativeObject)
 {
     using (var scope = new EditorGUILayout.HorizontalScope())
     {
         string result = string.Format("classname:{0}, name: {1}, size: {2}", nativeObject.className, nativeObject.name, ToMemorySize(nativeObject.size));
         EditorGUILayout.LabelField(result, GUILayout.MaxWidth(500));
         EditorGUILayout.Space();
         if (GUILayout.Button("Select", GUILayout.Width(50)))
         {
             this._diffWindow.SelectThing(nativeObject);
             this._diffWindow.Repaint();
         }
     }
 }
Example #6
0
        private Texture2D GetTexture(NativeUnityEngineObject nativeObject)
        {
            // If the texture has a name, try to match it to a loaded object
            if (!string.IsNullOrEmpty(nativeObject.name))
            {
                Texture2D[] loadedTextures = Resources.FindObjectsOfTypeAll <Texture2D>();

                for (int i = 0; i < loadedTextures.Length; i++)
                {
                    if (loadedTextures[i].name == nativeObject.name)
                    {
                        return(loadedTextures[i]);
                    }
                }
            }
            // None matched
            return(null);
        }
        internal bool IsRoot(ThingInMemory thing, out string reason)
        {
            reason = null;
            if (thing is StaticFields)
            {
                reason = "Static fields are global variables. Anything they reference will not be unloaded.";
                return(true);
            }
            if (thing is ManagedObject)
            {
                return(false);
            }
            if (thing is GCHandle)
            {
                return(false);
            }

            NativeUnityEngineObject nativeObject = thing as NativeUnityEngineObject;

            if (nativeObject == null)
            {
                throw new ArgumentException("Unknown type: " + thing.GetType());
            }
            if (nativeObject.isManager)
            {
                reason = "this is an internal unity'manager' style object, which is a global object that will never be unloaded";
                return(true);
            }
            if (nativeObject.isDontDestroyOnLoad)
            {
                reason = "DontDestroyOnLoad() was called on this object, so it will never be unloaded";
                return(true);
            }

            if ((nativeObject.hideFlags & HideFlags.DontUnloadUnusedAsset) != 0)
            {
                reason = "the DontUnloadUnusedAsset hideflag is set on this object. Unity's builtin resources set this flag. Users can also set the flag themselves";
                return(true);
            }

            if (nativeObject.isPersistent)
            {
                return(false);
            }

            if (IsComponent(nativeObject.classID))
            {
                reason = "this is a component, living on a gameobject, that is either part of the loaded scene, or was generated by script. It will be unloaded on next scene load.";
                return(true);
            }

            if (IsGameObject(nativeObject.classID))
            {
                reason = "this is a gameobject, that is either part of the loaded scene, or was generated by script. It will be unloaded on next scene load if nobody is referencing it";
                return(true);
            }

            if (IsAssetBundle(nativeObject.classID))
            {
                reason = "this object is an assetbundle, which is never unloaded automatically, but only through an explicit .Unload() call.";
                return(true);
            }

            reason = "This object is a root, but the memory profiler UI does not yet understand why";
            return(true);
        }
Example #8
0
 private string getRemoveDiffTypeStr(NativeUnityEngineObject things)
 {
     return(things.className.Replace(sDiffType.AdditiveType, "").Replace(sDiffType.ModificationType, "").
            Replace(sDiffType.NegativeType, ""));
 }
Example #9
0
        internal void Draw()
        {
            GUILayout.BeginArea(new Rect(_hostWindow.position.width - width, _hostWindow.topMargin, width, _hostWindow.position.height - _hostWindow.topMargin));
            _scrollPosition = GUILayout.BeginScrollView(_scrollPosition);

            GUILayout.BeginHorizontal();
            GUI.enabled = _backSelected.Count > 1;
            if (GUILayout.Button(string.Format("Back ({0})", Math.Max(0, _backSelected.Count - 1))))
            {
                _backSelected.Pop();

                if (_nextSelected.Count == 0 || _backSelected.Peek() != _nextSelected.Peek())
                {
                    _nextSelected.Push(_backSelected.Peek());
                }

                _hostWindow.SelectThing(_backSelected.Peek());
            }
            GUI.enabled = true;

            GUI.enabled = _nextSelected.Count > 1;
            if (GUILayout.Button(string.Format("Next ({0})", Math.Max(0, _nextSelected.Count - 1))))
            {
                _nextSelected.Pop();
                _hostWindow.SelectThing(_nextSelected.Peek());
            }
            GUI.enabled = true;
            GUILayout.EndHorizontal();

            if (_unpackedCrawl != null)
            {
                GUILayout.Label(string.Format("Total memory: {0}", EditorUtility.FormatBytes(_unpackedCrawl.totalSize)));
            }

            if (_selectedThing == null)
            {
                GUILayout.Label("Select an object to see more info");
            }
            else
            {
                NativeUnityEngineObject nativeObject = _selectedThing as NativeUnityEngineObject;
                if (nativeObject != null)
                {
                    GUILayout.Label("NativeUnityEngineObject", EditorStyles.boldLabel);
                    GUILayout.Space(5);
                    EditorGUILayout.LabelField("Name", nativeObject.name);
                    EditorGUILayout.LabelField("ClassName", nativeObject.className);
                    EditorGUILayout.LabelField("Memory amount", EditorUtility.FormatBytes(_selectedThing.size));
                    EditorGUILayout.LabelField("instanceID", nativeObject.instanceID.ToString());
                    EditorGUILayout.LabelField("isDontDestroyOnLoad", nativeObject.isDontDestroyOnLoad.ToString());
                    EditorGUILayout.LabelField("isPersistent", nativeObject.isPersistent.ToString());
                    EditorGUILayout.LabelField("isManager", nativeObject.isManager.ToString());
                    EditorGUILayout.LabelField("hideFlags", nativeObject.hideFlags.ToString());
                    DrawSpecificTexture2D(nativeObject);
                }

                ManagedObject managedObject = _selectedThing as ManagedObject;
                if (managedObject != null)
                {
                    GUILayout.Label("ManagedObject");
                    EditorGUILayout.LabelField("Type", managedObject.typeDescription.name);
                    EditorGUILayout.LabelField("Address", managedObject.address.ToString("X"));
                    EditorGUILayout.LabelField("size", managedObject.size.ToString());

                    if (managedObject.typeDescription.name == "System.String")
                    {
                        EditorGUILayout.LabelField("value", StringTools.ReadString(_unpackedCrawl.managedHeap.Find(managedObject.address, _unpackedCrawl.virtualMachineInformation), _unpackedCrawl.virtualMachineInformation));
                    }
                    DrawFields(managedObject);

                    if (managedObject.typeDescription.isArray)
                    {
                        DrawArray(managedObject);
                    }
                }

                if (_selectedThing is GCHandle)
                {
                    GUILayout.Label("GCHandle");
                    EditorGUILayout.LabelField("size", _selectedThing.size.ToString());
                }

                StaticFields staticFields = _selectedThing as StaticFields;
                if (staticFields != null)
                {
                    GUILayout.Label("Static Fields");
                    GUILayout.Label("Of type: " + staticFields.typeDescription.name);
                    GUILayout.Label("size: " + staticFields.size);

                    DrawFields(staticFields.typeDescription, new BytesAndOffset()
                    {
                        bytes = staticFields.typeDescription.staticFieldBytes, offset = 0, pointerSize = _unpackedCrawl.virtualMachineInformation.pointerSize
                    }, true);
                }

                if (managedObject == null)
                {
                    GUILayout.Space(10);
                    GUILayout.BeginHorizontal();
                    GUILayout.Label("References:", labelWidth);
                    GUILayout.BeginVertical();
                    DrawLinks(_selectedThing.references);
                    GUILayout.EndVertical();
                    GUILayout.EndHorizontal();
                }

                GUILayout.Space(10);
                GUILayout.Label("Referenced by:");
                DrawLinks(_selectedThing.referencedBy);

                GUILayout.Space(10);
                if (_shortestPath != null)
                {
                    if (_shortestPath.Length > 1)
                    {
                        GUILayout.Label("ShortestPathToRoot");
                        DrawLinks(_shortestPath);
                    }
                    string reason;
                    _shortestPathToRootFinder.IsRoot(_shortestPath.Last(), out reason);
                    GUILayout.Label("This is a root because:");
                    GUILayout.TextArea(reason);
                }
                else
                {
                    GUILayout.TextArea("No root is keeping this object alive. It will be collected next UnloadUnusedAssets() or scene load");
                }
            }
            GUILayout.EndScrollView();
            GUILayout.EndArea();
        }
Example #10
0
        private int CompareData(int id1, int id2, int col)
        {
            ThingInMemory           thing1        = m_unpackedCrawl.allObjects[id1];
            NativeUnityEngineObject nativeObject1 = thing1 as NativeUnityEngineObject;

            ThingInMemory           thing2        = m_unpackedCrawl.allObjects[id2];
            NativeUnityEngineObject nativeObject2 = thing2 as NativeUnityEngineObject;

            switch ((Column)col)
            {
            case Column.Name:
                if (nativeObject1 != null && nativeObject2 != null)
                {
                    return(nativeObject1.name.CompareTo(nativeObject2.name));
                }
                else if (nativeObject1 != null)
                {
                    return(-1);
                }
                else if (nativeObject2 != null)
                {
                    return(1);
                }
                else
                {
                    return(0);
                }

            case Column.Type:
                // this depends on the fact that HighLevelAPI.allGameObjects concatenates objects in the order we want
                return(id1 - id2);

            case Column.Size:
                return(-thing1.size.CompareTo(thing2.size));

            case Column.ClassName:
                if (nativeObject1 != null && nativeObject2 != null)
                {
                    return(nativeObject1.className.CompareTo(nativeObject2.className));
                }
                else if (nativeObject1 != null)
                {
                    return(-1);
                }
                else if (nativeObject2 != null)
                {
                    return(1);
                }
                else
                {
                    return(0);
                }

            case Column.InstanceID:
                if (nativeObject1 != null && nativeObject2 != null)
                {
                    return(nativeObject1.instanceID.CompareTo(nativeObject2.instanceID));
                }
                else if (nativeObject1 != null)
                {
                    return(-1);
                }
                else if (nativeObject2 != null)
                {
                    return(1);
                }
                else
                {
                    return(0);
                }
            }
            return(0);
        }
Example #11
0
        private GUIContent DataForGrid(int id, int col)
        {
            string                  str          = "undefined";
            ThingInMemory           thing        = m_unpackedCrawl.allObjects[id];
            NativeUnityEngineObject nativeObject = thing as NativeUnityEngineObject;

            switch ((Column)col)
            {
            case Column.Name:
                if (nativeObject != null)
                {
                    str = nativeObject.name;
                }
                if (str.Equals(""))
                {
                    str = "unnamed";
                }
                if (thing.ignored)
                {
                    str = "<filtered>";
                }
                break;

            case Column.Type:
                str = ThingTypeToString(indexToThingType(id));
                if (thing.ignored)
                {
                    str = "<filtered>";
                }
                break;

            case Column.Size:
                str = EditorUtility.FormatBytes(thing.size);
                if (thing.ignored)
                {
                    str = "<filtered>";
                }
                break;

            case Column.ClassName:
                if (nativeObject != null)
                {
                    str = nativeObject.className;
                }
                if (thing.ignored)
                {
                    str = "<filtered>";
                }
                break;

            case Column.InstanceID:
                if (nativeObject != null)
                {
                    str = nativeObject.instanceID.ToString();
                }
                if (thing.ignored)
                {
                    str = "<filtered>";
                }
                break;
            }

            return(new GUIContent(str));
        }