Search Unity

  1. Welcome to the Unity Forums! Please take the time to read our Code of Conduct to familiarize yourself with the forum rules and how to post constructively.
  2. The 2023.1 beta is now available for testing. To find out what's new, have a look at our 2023.1 feature highlights.
    Dismiss Notice

Official Memory Profiler 0.5 Released

Discussion in 'Profiler Previews' started by MartinTilo, Feb 3, 2022.

  1. MartinTilo

    MartinTilo

    Unity Technologies

    Joined:
    Aug 16, 2017
    Posts:
    1,910
    We released a big update to the Memory Profiler package today that marks a major milestone on it’s route to the 1.0 release.

    The broad strokes of the release is that we’ve drastically simplified the analysis of what references a given object in memory, as well as the workflow of diving into the details of that object. We have more on both of these points that we will add and improve upon going forward, but the new UI and workflow affordances should already alleviate a lot of issues that you have rightfully pointed out to us over the years.

    For now, we hope that this release helps speed up your workflows for memory analysis and that we can refine these further with your feedback.

    So let's dive into the release:


    (Click here for the full changelog for 0.5.0-preview.1 or here for a forum thread you can subscribe to in order to get notified of new releases of this package.)

    Details Panel
    When you select an item, such as a row in a table, a rectangle in the Tree Map or a bar or it's row in the Memory Usage Summary, the newly added right side panel will provide further information regarding that selection.

    The side panel has two sections:
    • References
    • Selection Details

    The References section shows data related to the selection within the main view panel, while the Selection Details section will provide information about the selection within the main view panel or within the references section.

    (Raw) References at a glance
    In previous versions of the Memory Profiler, what other objects referenced an object, and thereby possibly kept it in memory, was only visible as a blue link in the Referenced By column. To see the entire trail of references, one had to click through several screens, possibly going in circles.

    This information is now displayed in the References section as a Tree View. Clicking any of the tree's expand arrows while holding down the alt/option modifier key will expand the entire subtree (like in the rest of the editor), providing the full reference chain at a glance, pruned for cyclic dependency chains.

    Worth noting is that the references here might, but don't have to be the ones that keep an element in memory.

    For example: a managed object referencing the managed shell for a scene object in a different scene would keep the managed object in memory, even if the other scene is unloaded. The native object referenced by the managed shell would however be unloaded (and the managed shell "leaked" as a result).

    The current snapshot data is missing some information such as which scene a scene object is rooted to, which we are about to add to the data on the Unity Editor & Player side. A future update to the package and that extra data from the snapshots will allow us to make this view show significantly fewer items by filtering out references that may be informative for the purpose of seeing what is connected to what, but ultimately don't matter much in terms of what is keeping what in memory. These filtered views will be called "Path To Roots" or "Path From Roots" as we are considering a bottom-up and top-down variation for different workflows.

    As such, we are thinking of keeping this "Raw" version of the references even when we have the more helpful Path To/From Roots, A) as a fallback for snapshots from older Players/Editor's and B) for the curious that want to dive deeper than "What is holding this in memory" via the references.

    A last thing to note is that this view lists Managed Shell Objects and their Native Objects separately, while when you select either of them the Selection Details will show these as one item.

    Diving Deeper into References - a quick showcase
    Unity_8uGqGyEWnP2.png

    So let's examine the references to that InventorySlotBG object from the previous screenshot. As you can see, we’ve selected the Native Object part of this object, which is shown as the very first line in this view.

    Each Object inheriting from UnityEngine.Object (or it’s Native code equivalent) can have exactly one Managed Shell object that is used by Managed C# Code to access and handle this resource. You can see the Managed Shell of this Texture2D object directly in the second line. The Managed Shell object has a pointer back to the Native Object, so these 2 reference each other. Thus, it makes not much of a difference for the References view, which one of the two you selected, the first two lines might just be flipped.

    Next, this Texture is referenced by a Sprite of the same name, indicating that this Texture2D is imported as a Sprite. The Sprite is referenced by the Managed code of the Image component that derives from MonoBehaviour, which sits on a GameObject named “Background Image”.

    Now, technically our examination could stop here. We’ve hit the first GameObject reference. This GameObject will be referenced by other GameObjects, or rather, their Transform Components, within the Scene Hierarchy and ultimately roots this GameObject and the Texture to the Scene. Except, we don’t yet have the data in this snapshot, to identify which Transform is at the root of that hierarchy and which Scene it is placed in. This is where the additional Scene Root data and filtering is going to come in later.

    For the time being, the remaining references in this example can illuminate what other components are on that GameObject, and what is referencing those, which may help you identify it further if you just had its name.

    Also Note that the Texture2D Asset itself is marked as “Persistent”, which means that it is associated with a file and that the Persistent Manager is handling its live time and will unload it during Resources.UnloadUnusedAssets if it is no longer referenced, so just unloading the scene alone may not get rid of the memory just yet. That it is indeed marked as Persistent can be seen in the Selection Details.

    Selection Details

    The Selection Details has different sections based on the current selection. This example shows all of them.



    Name, Icons, Select and Search Buttons
    The selected Item is the Texture2D we’ve examined in the References view before. The view shows both its managed and native data, as indicated by the “#++” icon. The Asset is named “InventorySlotBG”, i.e. this is what you would get if you queried the .name property on its Managed Shell object.

    Every UnityEngine.Object has a name associated with its Native Object, but those created at run time (i.e. not loaded from a file) might not have one set. If you find an Object that doesn’t have a name, it may just be the leaked Managed Shell (the Status field will tell you as much) or you might want to find where in your project’s code that object is created or instantiated and make sure to set the .name property to something helpful.

    The Type Name in this case is the shortened form. You can toggle between seeing the full Managed Type Name (and the Native Type Name) by right-clicking the name or the table headers of the References or Managed Fields table. With this option turned off, this text displays as
    "<Native Object Name>" <Managed Type Name> : <Native Type Name>

    Unity_Q0B3rNfhnh.png

    When you selected the Object, the Memory Profiler went ahead and searched the project for something that matches this object’s name or type. If there was exactly one match, the “Select In Editor” button is activated and, if applicable, it’s preview is loaded.

    Please note that this is NOT GUARANTEED to be the same object, and that the Preview is not based on e.g. what the Texture looked like in the build, because the Texture pixel data is not captured within the snapshot. Instead this preview comes from within the current Editor Project, which may have different import settings or an entirely different or changed texture with the same name.

    That said, the “Select In Editor” will ping and select the object in the Editor, so you can use any Inspector to examine its details.

    If you just captured the current Editor instance, it may also just use the Instance ID directly to find the Object still in memory.

    If no exact match is found, you can use the Search buttons to look for it instead. This will filter the Scene View and Scene Hierarchy View (if it is a Scene Object) or the Project Browser Window if it is an Asset. In Editor versions 2021.1 or newer you can also directly open the search in the Quick Search window.


    Basic Info and Help
    The Basic info shows the total size as well as how that is split across the Managed and Native side of the Object. Similarly, the References field shows how many other objects are referencing this object, and that it is referencing “it-self”, i.e. the Native Object references the Managed Shell and vice versa.

    The Status field gives a brief, at a glance insight into what this object is, why it may have been loaded and why it may not have been unloaded yet. The Tooltip of that field, as well as the Help section below go into more details regarding that Status assessment, as well as tips for possible next steps.

    Advanced Info
    The information this section provides may be interesting for some very specific workflows. But mostly, what can be derived from this info has already been boiled down into the Status and Help section, but made easier to read.

    Preview Image
    As noted in the context of the Select and Search Buttons above, please note that the Preview is NOT based on e.g. what the Texture looked like in the build, because the Texture pixel data is not captured within the snapshot. Instead this preview comes from within the current Editor Project, which may have different import settings or an entirely different or changed texture with the same name.

    Managed Fields inspector
    The Managed Shell object for a Texture2D doesn’t have a whole lot of managed field data associated with it.

    There are the 2 static fields and the private field m_CachedPtr, which is how the Managed Shell references the Native Object underneath it. That Native object in turn, references the Managed one again via a GCHandle. To avoid going around in circles, this circular reference is cut short as it reaches around to the Selected Managed Object, as the Notes column indicates as well.

    Another relatively simple object that no less showcases an interesting use case for the Managed Fields inspector is this MonoBehaviour I wrote:

    It too has the static field (which is used internally for finding the instance ID on the Native Object) and the m_CachedPtr. Because this is a capture from the Editor, it also has a managed field for the Instance ID and an error string. These are used for the Missing component error messages in the Editor.

    The other fields however show that you can now see how much memory your scripts are referencing to in native memory, via IntPtr or in this example, Persistent NativeArrays.

    Details for Memory Usage Overview Categories
    We haven’t yet implemented Selection Details for all items you can select in the Memory Profiler, but we do have a basic implementation for the Memory Usage Overview Categories, which are now selectable. The Selection Details for those are currently just text that explains what they are in more detail than a tooltip could. We are looking at other possibilities for what information we could surface here and would love to hear your thoughts on this.


    Simplified Tables
    While we are already working on a new table UI to deliver more intuitive workflows than the existing table UI can provide, we have taken this release as an opportunity to reassess what needs to be displayed in the ones we already have.

    We’ve removed all links. They were cumbersome, prone to getting clicked on accidentally and made some key workflows hard to discover.
    • Given that References are now way easier to analyze in the References section, the Referenced By column no longer needed to link to a table of it’s direct Referrers.
    • Similarly, the Instance ID was no longer needed to ping an object in the Editor, and it only worked if the capture was made in the current Editor session anyways
    • Seeing details for just one Object, or examining the Native Object under a Managed Shell, can now be done right in the Selection Details, so Native Object Name and the Value column no longer needed a link
    Additionally, the Address moved to the Advanced section in the Selection Details and the Index column was entirely useless outside of debugging purposes for us. The Addresses column was also responsible for unfolding Managed Objects to inspect their fields and data layout, which is now moved to the Managed Fields section in the Selection Details. With that move, the Static, Length, Managed Size and Target Field Size columns became obsolete too, and since the tables show Managed Objects and Native Objects separately anyways, only one Size column remained.

    The Value column is still the easiest, at a glance, way of looking at a brief glimpse of the fields of a Managed Object, so it remains for now.

    So with all that in mind, we decided to hide all these now (mostly) obsolete columns) and provide you with the ability to show them again if absolutely required. (We are aware that this choice is not saved. Please let us know if you have any workflows that you require these columns for so that we can consider that for the new table UI.)

    Lastly, we re-arranged the order of the columns in a way that felt more intuitive and better prioritized to us. This leaves us with this set of columns in the extreme case (Diff All Objects):



    As you can see, we also added a much requested Count and Total Size summary above the table, tha updates as you filter the table. Given that we now hide the expandable bit of Managed Objects and only have one Size column, this was now straightforward, but may have some odd edge cases if you add the now hidden columns again.

    Feedback
    As mentioned in several places above, this update does not deliver the final workflows we are envisioning, but are a major step towards them, that we would love to get your feedback on. So even though we believe to have a good understanding and vision for what is needed, your feedback to us along this road is going to be critical in order for us to be able to deliver you the Memory Profiler workflows you deserve.
    • Do these new views help you in analyzing your apps memory usage more quickly and clearly?
    • Is there anything that you are missing or that is confusing in these views?
    • Did we break your workflow by hiding some columns by default?
    Or just whatever else you have in mind regarding this update and the status of the tool in general.

    You can send us your feedback by replying to this thread and/or via this quick survey questionnaire, or by opening new threads within the Profiler Previews subforum.
     
    Last edited: Feb 24, 2022
  2. TJHeuvel-net

    TJHeuvel-net

    Joined:
    Jul 31, 2012
    Posts:
    751
    Just sent the feedback survey, but wanted to add one thing:

    upload_2022-2-7_9-50-8.png
    Suddenly we have a new Examples menu item, dont think that was intentional? EditorAssetFinderUtility.cs
     
    MartinTilo and alexeyzakharov like this.
  3. MartinTilo

    MartinTilo

    Unity Technologies

    Joined:
    Aug 16, 2017
    Posts:
    1,910
    Thank you :)
    And yeah this one slipped the cracks and we've been alerted to it here. It's already fixed and the fix will ship with 0.5.1.

    Some other known issues fixed in 0.5.1:
    - NativeArray<>[] type fields get displayed incorrectly in the Managed Field inspector
    - Generic Type names get oddly Truncated when Truncate Managed Type's is enabled
    - Some duplicated entries in the References.
    - Improved accuracy in finding Assets and scene objects and their preview for the Selection Details in 2021.2 or newer

    Some other Known Issues of 0.5. we are looking to fix:
    - Exceptions on maximizing minimizing the Memory Profiler Window
    - High memory usage overhead for the snapshot's preview images

    things we are aware of but might fix a bit later due to pending rework:
    - Sorting the tables of the Memory Usage Overview bars is broken
    - Memory Usage Overview in diff mode doesn't show a sign on the diff column (+/-)
     
    Last edited: Feb 7, 2022
  4. TJHeuvel-net

    TJHeuvel-net

    Joined:
    Jul 31, 2012
    Posts:
    751
    When im browsing the referenced by view, the summary view seems to refresh and redraw. Why is that, the selection doesnt actually change?

    I suspect this causes a hang in the UI, every time i select another row in the Referenced By screen there is a progress bar.
     
  5. MartinTilo

    MartinTilo

    Unity Technologies

    Joined:
    Aug 16, 2017
    Posts:
    1,910
    Yes, the main view needs to change from active selection (blue row) to latent selection (gray row) when a secondary selection is being made. That said we've spotted some issues around this as well and have a fix for those upcoming in 0.5.1 :)
     
    TJHeuvel-net likes this.
  6. TJHeuvel-net

    TJHeuvel-net

    Joined:
    Jul 31, 2012
    Posts:
    751
    One more thing, small enough not to open a new thread.

    Either i'm a really good developer, or more likely, this "Top Issues" isnt very useful yet? Can you share what plans there are for issues, and could we make our own issue detector? How in depth can this be, can it find read/write enabled for textures and meshes?

    upload_2022-2-23_11-44-11.png
     
    Last edited: Feb 23, 2022
    MartinTilo likes this.
  7. MartinTilo

    MartinTilo

    Unity Technologies

    Joined:
    Aug 16, 2017
    Posts:
    1,910
    Yeah so, some of this depends on us to add more context to the data, like Meta Data for textures that contains their format and some crucial settings like Read Write enabled, but part of that is based around existing possibilities that are mostly waiting for a UI solution to more cleanly investigate these.

    For example, there are some Statuses shown in the Selection Details that we know are clear issues, such as Leaked Managed Shell Objects. We don't yet have a filtered view into these, but once we do, we'd list

    "X Leaked Shell Objects taking up Y KB of memory themselves and holding partially or solely 'own' Z MB memory due to referencing it. [Show Filtered List]"

    It's not always easy to distinguish what is an Issue or has a legitimate use case. We have 3 verbosity levels for that, Error, Warning and Info, and Error should only ever be used when we're certain that this shouldn't be the case.

    Leaked Shell Objects are one of the saver bets for "Wrong/Error" behavior. There might be awkward inbetween moments during level loading or such, where they could legitimately be "about to be unreferenced and GC Collected" but normally they are very indicative of an issue.

    Other cases are less straight forward.

    That would be a Warning for example, as that may be legit on some of them. As mentioned, that would need that context info though. We could grab some of that info it from the current editor project, but that's a bit flimsy and might not reflect the status in the captured build. So ideally we want to get the info out of context data in the snapshot, just to be sure we're not "crying wolf" in vain.

    Right now it mostly informs about stuff like "Objects in the mirror Editor might appear larger than they are in reality a build", current shortcomings of cross session or cross editor version comparisons or snapshots from older unity versions that may be lacking some data.

    Possible other future Messages there could be:
    - Number and memory usage of possible duplicates
    - Number and memory usage of Leaked Unreferenced Dynamically created assets
    - Number and memory usage of Objects only held by the DontDestroyOnLoad Flag

    The later two are also part of the potentially problematic Statuses that are already called out in the Selection Details.

    We're more than happy to hear any ideas on what people think could be called out in there.
     
    TJHeuvel-net likes this.
  8. TJHeuvel-net

    TJHeuvel-net

    Joined:
    Jul 31, 2012
    Posts:
    751
    Sounds great, the categories make a lot of sense.

    Would it be possible to sort, or search, by warning? For example i'd really like to see all the textures that are readable, being able to only show Texture entries with a warning containing "readable" might be a sensible way?
     
  9. MartinTilo

    MartinTilo

    Unity Technologies

    Joined:
    Aug 16, 2017
    Posts:
    1,910
    Yeah something like that would be the idea. It could be that initial it's just gonna be a dedicated list for each of these until we upgrade the new table ui we're building to be able to filter by flags. But basically, if we add an "Issue" there will be a filtered view into the data it sees an issue with.
     
    TJHeuvel-net likes this.
  10. berniegp

    berniegp

    Unity Technologies

    Joined:
    Sep 9, 2020
    Posts:
    35
    Hi! By the way, you can search for read/write textures and meshes in your project outside of the memory profiler with the Search window. Maybe this helps for this specific use-case? You can read more about it in this blog post. Search is a core feature in 2021+, but it's also available as a preview package for 2020 LTS (3.0.x). For the docs on the latest Search features, go to the 2021.2 docs (i.e. not the package docs) or check this wiki.
     
    MartinTilo likes this.
  11. MartinTilo

    MartinTilo

    Unity Technologies

    Joined:
    Aug 16, 2017
    Posts:
    1,910
  12. sabojako

    sabojako

    Joined:
    Jul 7, 2017
    Posts:
    48
    Hey there,

    In tried importing 0.5.1-preview.1 and 0.6.0-preview.1 in Unity 2021.1.9f1, but there's a compilation error:

    Library\PackageCache\com.unity.memoryprofiler@0.5.1-preview.1\Editor\Utilities\EditorAssetFinderUtility.cs(538,29): error CS0246: The type or namespace name 'SearchViewState' could not be found (are you missing a using directive or an assembly reference?)

    Probably need to bump the minimum version so they don't show up in Package Manager? Or maybe you can avoid using SearchViewState so it can be more compatible with earlier versions? :) (the current min version seems to be 2019.4 !)
     
  13. MartinTilo

    MartinTilo

    Unity Technologies

    Joined:
    Aug 16, 2017
    Posts:
    1,910
    Hi @sabojako,

    That issue is fixed in the upcoming 0.6.1 release but the 2021.1 Tech release was technically no longer supported when those versions were released, so we didn't test against it. The way the Tech and LTS release system works means you shouldn't actually stay on an outdated Tech release and expect updates to packages to work on these.
     
    sabojako likes this.
  14. ChloeGue

    ChloeGue

    Joined:
    May 11, 2019
    Posts:
    11
    Hi,
    I am using the Editor version 2021.1.13 and I have the same issue as above:

    Library\PackageCache\com.unity.memoryprofiler@0.6.0-preview.1\Editor\Utilities\EditorAssetFinderUtility.cs(538,29): error CS0246: The type or namespace name 'SearchViewState' could not be found (are you missing a using directive or an assembly reference?), and the upcoming 0.6.1 is still not available.

    Can you please assist?

    Thanks a lot,
    Chloé.
     
  15. MartinTilo

    MartinTilo

    Unity Technologies

    Joined:
    Aug 16, 2017
    Posts:
    1,910
    Yep, apologies for the delay, 0.6.1 is now slated for release next week so that should fix that issue.
     
  16. MartinTilo

    MartinTilo

    Unity Technologies

    Joined:
    Aug 16, 2017
    Posts:
    1,910
    Quick update for @ChloeGue & @sabojako:

    Since we removed a Type that was used for old snapshot file (de/)serialization that had accidentally been declared as public, we had to bump the release version from 0.6.1 to 0.7.0 but that release is now live and fixes that compilation issue.

    That said, you'll really want to be on the latest supported versions of whichever major Unity version release you are on, so in your case 2021.3.x. Bugfixes, including those increasing the accuracy of the numbers reported to the Memory Profiler will only land on these and will affect how well you'll be able to optimize your memory usage with this tool.
     
    sabojako likes this.