Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Utilities ░ ▒ ▓ █ Heap Explorer - Memory Profiler, Debugger and Analyzer for Unity

Discussion in 'Tools In Progress' started by Peter77, Apr 22, 2018.

  1. Peter77

    Peter77

    QA Jesus

    Joined:
    Jun 12, 2013
    Posts:
    6,586
    I had two reasons:
    • Unity's Memory Profiler was on Bitbucket and I wanted a familiar location for users of that tool
    • I had a Bitbucket account already
     
  2. pavelkouril

    pavelkouril

    Joined:
    Jul 22, 2016
    Posts:
    129
    Just an idea; at the moment, the "unknown" types are skipped, e.g., this error:

    ERROR: 'System.Collections.Generic.Dictionary.Entry<System.Int32,System.Globalization.CultureInfo>[].baseOrElementTypeIndex' = -1 is out of range, ignoring. Details in second line
    arrayRank=1, isArray=True, typeInfoAddress=2141349E5C0, address=21409CD3930, memoryreader=MemoryReader, isValueType=False


    Do you think it would be possible instead of skipping them altogether, resolving them as a simple "object" (or some bogus type), so they still get shown in the C# Managed Objects, and we do not lose possible references to the address/from the address (if there is any)? Or would this not make any sense, since there would be no references for these objects?
     
    Peter77 likes this.
  3. Peter77

    Peter77

    QA Jesus

    Joined:
    Jun 12, 2013
    Posts:
    6,586
    I guess if I set the
    baseOrElementTypeIndex
    to
    System.Object
    or so, it would cause other issues, because the memory layout of the unknown object does not match the layout of System.Object.

    Do you know how Unity's new MemoryProfiler handles this case?

    PS: To my future self, it's caused by this issue.
     
  4. r2digi

    r2digi

    Joined:
    Sep 26, 2013
    Posts:
    24
    this looks fantastic. great job!
     
    Peter77 likes this.
  5. Peter77

    Peter77

    QA Jesus

    Joined:
    Jun 12, 2013
    Posts:
    6,586
    Last edited: Jun 26, 2019
    MartinTilo likes this.
  6. LazloBonin

    LazloBonin

    Joined:
    Mar 6, 2015
    Posts:
    809
    Did you ever get a chance to have a look at this issue?
     
  7. Peter77

    Peter77

    QA Jesus

    Joined:
    Jun 12, 2013
    Posts:
    6,586
    Nope, I haven't looked at this issue any further. Unity staff wrote they wanted to change the "exclude uninitialized/unused types" behavior, in which case I believe this issue should just disappear. I'm also not sure if Heap Explorer is still used, because Unity released new Memory Profiler a while ago.
     
  8. Joerg-Boehnel

    Joerg-Boehnel

    Joined:
    Jun 24, 2013
    Posts:
    30
    Heap Explorer is still way better then the Unity Momory Profiler (preview 8, atm of writing) and I use it on a regular basis; whenever I have to find memory leaks/usage. Main reasons I prefer HeapExplorer:

    * Shortest path to root: UnityMemoryProfiler still doesn't have that feature
    * speed: HeapExplorer is faster

    So thank you very much for all the work you put into HeapExplorer, right now I'd say it is the best option to track down memory usage/leaks.
     
    Noisecrime and Peter77 like this.
  9. Peter77

    Peter77

    QA Jesus

    Joined:
    Jun 12, 2013
    Posts:
    6,586
    That's music to my ears, thanks a lot for the positive feedback and great to hear the tool proved to be useful! I'm surprised Unity's new Memory Profiler isn't light years ahead of Heap Explorer already.

    One of my most important goal for Heap Explorer was to make it faster than their old memory profiler. I believe in most cases I succeeded, but I've also seen a few snapshots where the tool is also really sloooow.

    What Unity version do you use? I wonder if it works with Unity 2019. Perhaps I should dig out the code and see if there is some low hanging fruit. I mean if the tool is still used...
     
    Noisecrime likes this.
  10. Joerg-Boehnel

    Joerg-Boehnel

    Joined:
    Jun 24, 2013
    Posts:
    30
    Currently we're using 2019.1 but about to switch to 2019.3 soonish.
     
  11. Noisecrime

    Noisecrime

    Joined:
    Apr 7, 2010
    Posts:
    2,035
    I remember using HeapExplorer way back and thought it was a great improvement over the Memory Profiler at the time. I had assumed that the new Memory Profiler would be better and regularly updated, however it sounds like that hasn't happened? In which case I just wanted to say i'd most likely use Heap Explorer again when I need that functionality, so its certainly not a dead tool to users.
     
    Peter77 and Alloc like this.
  12. MartinTilo

    MartinTilo

    Unity Technologies

    Joined:
    Aug 16, 2017
    Posts:
    2,424
    Performance issues and lacking shortest path to root feature are on our roadmap for memory profiler. So far, the biggest issues we had to focus on where in the back-end though. Among quite a few others, the way connections where collected was super slow and didn't make much of any sense. e.g. there was a lot of redundant info in the connections. There was also little sense in focusing on doing a shortest path to root feature when the data was structured as it was and the performance of it would've also not been great with all the superfluous data ;)

    So 2019.3 comes with a pruned list of connections, taking snapshots got quite a bit faster (not just due to the faster collection of connections), there's next to no additional memory needed to be allocated for capture, as the managed heap now gets streamed out, and other fixes that we came across along the way. Heap Explorer benefits from this as well as it's mostly back-end changes, that said, @Peter77, you might indeed want to checkout the latest releases of 2019.3 and 2020.1 as there might be some small tweaks needed to adjust Heap Explorer for these versions.

    Also, feedback heard and received, we'll continue to improve the Memory Profiler, hopefully in a better cadence now that most back-end issues we're aware of are resolved. There is some restructuring still pending for the UI code but overall the cadence should pick up.
     
    Peter77, Noisecrime and SugoiDev like this.
  13. Joerg-Boehnel

    Joerg-Boehnel

    Joined:
    Jun 24, 2013
    Posts:
    30
    That's great to read, OutOfMemory while creating a snapshot is one of the biggest problems right now. I'm looking forward to the update :)
     
  14. Peter77

    Peter77

    QA Jesus

    Joined:
    Jun 12, 2013
    Posts:
    6,586
    Thanks for the kind words! It's the kind of feedback that keeps me motivated to work on these kind of things, so hearing this once in a while is great.

    That's great news, sounds like you fixed this issue?!

    Thank you for the info! Do you know if you use Heap Explorer internally to check if the Memory Profiling API changes still work and are backwards compatible?
     
  15. MartinTilo

    MartinTilo

    Unity Technologies

    Joined:
    Aug 16, 2017
    Posts:
    2,424
    Well that one was closed as By Design somehow but yes, there was this other case on this as well that got closed as part of this. Basically the connections previously were gathered by following the same code path used by the AssetGC so it was... Technically correct? :oops:

    Anyways that took some rewriting of backend code by @alexrvn that landed in 2019.3.0b9 and 2020.1.0a11 and a slight API change that meant the Memory Profiler package actually didn't compile against it anymore (that's accounted for in 0.1.0-preview.8) so I'd guess HeapExplorer would also throw a compiler error. And to answer your other question with that, no we don't use Heap Explorer internally to check against API changes, though some do use it internally, especially on pre 2018.3 versions.
     
    Peter77 likes this.
  16. Peter77

    Peter77

    QA Jesus

    Joined:
    Jun 12, 2013
    Posts:
    6,586
    This is the kind of feedback that motivates! I'll check if Heap Explorer is causing issues with 2019.3 and 2020.1. Hopefully they're easy to fix ;)

    I'm thinking to create a package of Heap Explorer that can be installed through Unity's Package Manager. I'll have to take a closer look at compatibility though, as I imagine Unity 2017 isn't really ready for packages and .asmdef files. At least it wasn't the last time I checked.
     
    alexrvn, MartinTilo and SugoiDev like this.
  17. alexrvn

    alexrvn

    Unity Technologies

    Joined:
    May 16, 2017
    Posts:
    53
    @Peter77 it's just one extra field that allows direct access to a native object's gc handle index, and handling the Connections array as instance ids instead of indices ^^
     
    Peter77 and MartinTilo like this.
  18. yash_sg

    yash_sg

    Joined:
    Oct 29, 2018
    Posts:
    10
    Great work.:) Very useful tool.
    Also, this do work with Unity 2017.4.26 LTS.;)
    if anyone is working on 2017.4 you can easily upgrade to 2017.4.26 and use it.
     
    Peter77 likes this.
  19. DevinW

    DevinW

    Joined:
    Jun 19, 2014
    Posts:
    36
    This tool has been instrumental in helping us get onto Oculus Quest - We are using 2018.4.13f1 and haven't run into any major issues.

    The captures are much faster than Unity's capture tool and break down the data into a well readable format. In a perfect world, I want both of the tool's data visualizations and the speed of the heap explorer.

    Thanks a lot for authoring this and keeping an eye on it over the years. :)
     
    Peter77 likes this.
  20. chanon81

    chanon81

    Joined:
    Oct 6, 2015
    Posts:
    168
    Any updates on Heap Explorer working with 2019.3?
     
    Peter77 likes this.
  21. joshcamas

    joshcamas

    Joined:
    Jun 16, 2017
    Posts:
    1,276
    Amazing asset, I honestly am beyond astounded on how good it is - way beyond what Unity's does in every way, shape, and form.

    However, is there any way to look at the contents of a Texture2D that is not an asset?
     
    Last edited: Dec 23, 2019
    Peter77 likes this.
  22. Peter77

    Peter77

    QA Jesus

    Joined:
    Jun 12, 2013
    Posts:
    6,586
    How could I miss all the recent posts here?!

    Thanks so much for the kind words and feedback! I'm always happy to hear if the tool was of help. I'm really astonished to receive such positive feedback, even after Unity released their new Memory Profiler.


    I started to work on 2019.3 compatibility a while ago, there wasn't much of an issue with it though, or I didn't find the issues yet. Mostly editor UI styles that don't exist in 2019.3 anymore.

    I'm going to release "Heap Explorer for 2019.3 and newer" as a package that can be installed through Unity's Package Manager window. I'll make the package and source code available on github when it's finished.


    Unfortunately there isn't, at least no way that I'm aware of.

    When I worked on Heap Explorer during 2017/2018, Unity's Memory Profiling API didn't support to collect/sent the actual native memory, where someone could reconstruct the texture data from, for example. I'm not sure if this has changed in the meantime.


    Thanks for the info, I'm going to take a look at this as well. This change can be found in Unity 2020.1?
     
    yash_sg, chanon81 and joshcamas like this.
  23. joshcamas

    joshcamas

    Joined:
    Jun 16, 2017
    Posts:
    1,276
    Ahh I see. I wonder if I could do something crazy like dumping the memory after scanning, and then finding the address of the texture and trying to find it that way.
     
  24. Peter77

    Peter77

    QA Jesus

    Joined:
    Jun 12, 2013
    Posts:
    6,586
    If the texture uses "Read Write Enable", then a copy of that texture should be kept in main memory and probably included if you take a memory dump with visual studio, but that sounds complicated.

    If you only want to take a look at the texture, then I would recommend you check out RenderDoc.

    Edit: you could also just save your runtime texture as a file and look at it this way.
     
  25. joshcamas

    joshcamas

    Joined:
    Jun 16, 2017
    Posts:
    1,276
    The reason I'm trying to look at a texture is because I have no clue about its origin, and I'm trying to figure it out. For some reason I have a bunch of massive (50mb) textures that show up in memory but they aren't named (I name all textures I generate) and they aren't assets. So I'm just trying to find some sort of way of figuring out what's going on with that x)
     
  26. Peter77

    Peter77

    QA Jesus

    Joined:
    Jun 12, 2013
    Posts:
    6,586
    I this case, I would try to find then via Resources.FindObjectsOfTypeAll and just display them. For example by assigning them to a RawImage. This allows yoh to see their content.
     
    joshcamas likes this.
  27. slikeytre

    slikeytre

    Joined:
    Sep 12, 2018
    Posts:
    1
    Looking forward to the newer version this has been my goto for just finding things to optimize and locate leaks. Keep up the good work :)
     
    Peter77 likes this.
  28. alexrvn

    alexrvn

    Unity Technologies

    Joined:
    May 16, 2017
    Posts:
    53
    Yeap the aforementioned change is in 19.3 and above
     
  29. wwweh

    wwweh

    Joined:
    Oct 15, 2012
    Posts:
    18
    Just wanted to drop in and say this asset is amazing and has saved my ass multiple times!
     
    Peter77 and Alloc like this.
  30. nukeustwo

    nukeustwo

    Joined:
    Sep 4, 2015
    Posts:
    51
    Just a reminder about this @Peter77 :)

    The UX of heap explorer is much better than Unity's men profiler atm, one example for me is tracking which object is responsible for a given allocation is way more understandable and easier.

    Our studio will defo keep using this as long as you have the energy to keep putting into it (or until unity eventually agrees to buy you out :p) so looking forward to the 19.3 upgrade as we're currently upgrading our projects to .3
     
    Peter77 and Alloc like this.
  31. Peter77

    Peter77

    QA Jesus

    Joined:
    Jun 12, 2013
    Posts:
    6,586
    I guess @MartinTilo would be quite interested to learn more details about this and then hopefully improve some of the Unity Memory Profiler UX.

    I actually did start working on a Heap Explorer version for 2019.3, but it's been a while ago already and other things caught my interest.

    I just checked and realized I didn't commit anything and now it's too long for me to remember what all these changes are :rolleyes: I'll start this over and commit every single change to a 2019.3 branch to Bitbucket. It will not be 2019.3 ready in one go, but we'll get there eventually.

    Did you run in any problems with 2019.3? Because I remember on first sight everything looked fine, but going in deeper revealed a few issues that I can't remember anymore.

    Thanks for the kind words!
     
    MartinTilo likes this.
  32. MartinTilo

    MartinTilo

    Unity Technologies

    Joined:
    Aug 16, 2017
    Posts:
    2,424
    Indeed I am ;)
    Is this because of Paths to Root? Could you maybe just get into a bit more detail of what you're looking for and what helped and what didn't help you get it solved?
     
    Peter77 likes this.
  33. nukeustwo

    nukeustwo

    Joined:
    Sep 4, 2015
    Posts:
    51
    Hello! I actually need to do some memory profiling of our game today so I'll take the opportunity to do a bit of compare and contrasting between heap explorer + unity mem profiler and gather some thoughts and post 'em here
     
    Peter77 and MartinTilo like this.
  34. nukeustwo

    nukeustwo

    Joined:
    Sep 4, 2015
    Posts:
    51
    Okay so I think the main reason I prefer heap explorer is that it just exposes information that I care about quicker and "better"

    1.) Heap explorer shows the total memory used by type, unity mem prof has the map (which is cool) but doesn't show totals, so you have to kind of guesstimate based on area use of types
    Screenshot 2020-04-20 at 12.11.21.png

    2.) Heap explorer also shows you the count when you dive in, which mem profiler doesn't
    Screenshot 2020-04-20 at 12.12.15.png
    (by contrast, inspecting this by eye is not easy)
    Screenshot 2020-04-20 at 12.12.19.png

    3.) But yeah Martin as you guessed, the main thing I care about is "okay this memory is used, I want to know what is referencing it in the scene"
    In heap explorer this is immediately present as you select an object
    Screenshot 2020-04-20 at 12.18.43.png

    In Memory profiler, I have to click the "Referenced number" column number, which is both not obvious and an additional click.

    That's some concrete things, in general I just feel that the heap profiler UX is a better experience, and small differences make a big enough difference to use it over the unity mem profiler.

    As an aside :D - both the heap explorer and unity mem profiler show ~500mb used (device capture), but the device itself shows > 1gb used

    Screenshot 2020-04-20 at 12.10.56.png

    What sort of things are typically untracked?
     
    Noisecrime and Peter77 like this.
  35. nukeustwo

    nukeustwo

    Joined:
    Sep 4, 2015
    Posts:
    51
    Ps. that being said, both tools in general are super valuable, I'm not trying to hate on unity mem profiler :D
     
    Peter77 likes this.
  36. Peter77

    Peter77

    QA Jesus

    Joined:
    Jun 12, 2013
    Posts:
    6,586
    Thank your for the comparison, always great to have something like that :)

    I noticed the same problem. Unity's MemorySnapshot API didn't include various things at the time I created Heap Explorer. I doubt it has been fixed, because the issues I reported have been marked as "Won't fix" and "By design" ¯\_(ツ)_/¯
    Additionally, I've also a case that didn't make it into the public issue tracker for some reason, but it's still open:
    (Case 989625) PackedMemorySnapshot: ExecutableAndDlls memory missing
     
    Noisecrime and nukeustwo like this.
  37. nukeustwo

    nukeustwo

    Joined:
    Sep 4, 2015
    Posts:
    51
    Yeah, my current guess is streaming assets are accounted for in ways that may not be trackable, I've got a suspicion that ours is mostly down to wwise sound banks but will investigate properly
     
  38. MartinTilo

    MartinTilo

    Unity Technologies

    Joined:
    Aug 16, 2017
    Posts:
    2,424
    Thanks for the Feedback @nukeustwo!
    That's really valuable. Please note that the points below are more of a workaround of the current UX and as you're comparison pointed out by far not ideal:
    2) if you select a Type block in the Memory map, the table underneath is filtered to show only objects of the same type as that shown group, but as a table. A horribly cluttered table ... but still ;)

    I guess most of what's unreported is Plugins and DLLs, as @Peter77 mentioned. It doesn't have a public issue tracker because we've categorized it as a Feature Request rather than a bug. It's something that was somehow overlooked by the API originally written for the Hackweek project that became the BitBucket memory profiler and wasn't revisited when building the new API and UI i.e. for "hysterical" reasons ;) We're definitely planning to remedy that though.

    Native Array memory is reported. In the Memory Profiler you can find it in the Alloc > byNativeObject table under the AreaName "NativeArray". The content is not managed data though so not inspectable as you might expect it to be, given that you wrote that code in C#. It just reports the allocations and their sizes. i.e. this is not the culprit of underreporting (unless you only count memory from Managed and native objects but that's generally wrong) There is also the difference between Reserved memory (for heaps and pools) and Used memory (by allocations & objects)...

    This isn't a bug but a feature difference and should actually allow you to get closer to the data reported by e.g. Instruments. The Profiler's Memory Profiler Module just doesn't currently count Mono/IL2CPP allocations that are not the heaps where your managed objects reside in but e.g. Type metadata, and additional memory used by e.g. generics or caused by reflection. So this isn't the culprit either, unless you're counting the totals wrong, or not at all, as is the case in the memory profiler today...
     
    Peter77 likes this.
  39. MartinTilo

    MartinTilo

    Unity Technologies

    Joined:
    Aug 16, 2017
    Posts:
    2,424
    That'd be plugin memory I guess. So very likely. People building native DLL's to use with Unity can currently not report their memory usage to Unity and Unity has no visibility into their Malloc/Free etc. allocations.
     
    nukeustwo likes this.
  40. nukeustwo

    nukeustwo

    Joined:
    Sep 4, 2015
    Posts:
    51
    Ah I see, to double check my assumptions - what unity tracks is down to C/C# allocations with a call-stack that ultimately allocates from the engine, whereas DLLs can of course do this entirely outside of a malloc that is code in the engine?

    Makes sense - presumably there isn't a way of doing something like:
    * Unity.dll has loaded DLL's A and B
    * DLL A has allocated X memory (presumably the OS' tracks this relationship?)
    * Unity can query the OS for total DLL memory use for DLLs it has loaded
    * Show this info in a mem capture with at least a breakdown of DLLs plus total kb belonging to them

    Glad the feedback is useful and thanks for the workaround suggestion as well.
     
    MartinTilo likes this.
  41. MartinTilo

    MartinTilo

    Unity Technologies

    Joined:
    Aug 16, 2017
    Posts:
    2,424
    correct
    Asking the OSs (and maybe offering a plugin interface to report allocations from within a plugin) is what we need to do to cover this ground too, correct.
     
  42. nukeustwo

    nukeustwo

    Joined:
    Sep 4, 2015
    Posts:
    51
    Heh, cool, I'll put in a feature request with our support dude - is that useful or is this somewhere in the roadmap already?
     
  43. nukeustwo

    nukeustwo

    Joined:
    Sep 4, 2015
    Posts:
    51
    The Xcode allocations debugger is *sick* by the way, good for getting an idea on what the untracked memory allocations are, for us there are 350mb of metal library allocations

    Screenshot 2020-04-21 at 10.10.24.png
     
    Peter77 likes this.
  44. MartinTilo

    MartinTilo

    Unity Technologies

    Joined:
    Aug 16, 2017
    Posts:
    2,424
    That's not necessary. I've captured the feedback and added the feature request to our backlog. :)

    Thanks again for the feedback!
     
    Noisecrime likes this.
  45. friuns3

    friuns3

    Joined:
    Oct 30, 2009
    Posts:
    307
    This is way better than unity memory profiler! Unity profiler just throws you random stuff that you cannot search or sort properly.

    Works very well with .net 4.6
     

    Attached Files:

    Last edited: Apr 26, 2020
    Peter77 likes this.
  46. friuns3

    friuns3

    Joined:
    Oct 30, 2009
    Posts:
    307
    upload_2020-4-27_0-50-25.png
    Referenced by could be made clickable, so i could jump to next reference
     
  47. Peter77

    Peter77

    QA Jesus

    Joined:
    Jun 12, 2013
    Posts:
    6,586
    The "C#" icon next to the text is a clickable button that jumps to the object. This works across all lists in Heap Explorer.
    • "C#" icon jumps to C# object
    • "C++" icon jumps to the native object
    • "S#" icon jumps to the C# static object reference
    In Unity 2019.3 with the overhauled UI, it makes it harder to read these at buttons. This was more obvious in older Unity releases.
     
    friuns3 likes this.
  48. friuns3

    friuns3

    Joined:
    Oct 30, 2009
    Posts:
    307
    weird thing that neither unity memory profiler or Heap explorer not showing some objects

    i did basic object counter and its showing there still objects in memory, after i load new scene, doing gc collect and Resources.unloadUnusedResources, old objects accumulating for some reason.

    Code (CSharp):
    1.  
    2. internal static Dictionary<string, int> m_typeDictionary = new Dictionary<string, int>();
    3.  
    4. public BaseTransform()
    5. {
    6.     typeName = this.GetType().Name;
    7.     objectCount++;
    8.     m_typeDictionary[typeName]++;
    9. }
    10. ~BaseTransform()
    11. {
    12.     m_typeDictionary[typeName]--;
    13.     objectCount--;
    14. }
     
  49. Peter77

    Peter77

    QA Jesus

    Joined:
    Jun 12, 2013
    Posts:
    6,586
    I'm sorry that it took so long, but here it finally is: Heap Explorer for Unity 2019.3 provided as an elegant Unity Package. :)

    Download
    https://github.com/pschraut/UnityHeapExplorer

    What's new in 3.2?
    • Moved Heap Explorer menu item from "Window > Heap Explorer" to "Window > Analysis > Heap Explorer"
    • Removed "The MemoryProfiling API does not work with .NET 4.x Scripting Runtime" warning, because apparently Unity Technologies fixed this issue in the meanwhile.
    • Removed Beta notice and note about Heap Explorer not working with .NET 3.5, because there is no .NET3.5 in Unity 2019.3 anymore.
    • Fixed "Unable to find style 'TL SelectionBarCloseButton' in skin 'LightSkin' Layout" warning when opening Heap Explorer.
    • Fixed per frame warning "null texture passed to GUI.DrawTexture" when the C# Hex Viewer was open.
    • Fixed "Open Profiler" button not working due to error "ExecuteMenuItem failed because there is no menu named 'Window/Profiler'".
    • Moved documentation from PDF to github. It's not complete yet, but I wanted to get this release out.
    • Moved repository from bitbucket to github

     
    Last edited: May 1, 2020
  50. friuns3

    friuns3

    Joined:
    Oct 30, 2009
    Posts:
    307
    awesome its alive! btw i been using previous version with 2019.3 and it did work just fine