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. Dismiss Notice

Question What on earth is "Reserved" memory and why is killing me?

Discussion in 'Editor & General Support' started by hypnoslave, Dec 8, 2022.

  1. hypnoslave

    hypnoslave

    Joined:
    Sep 8, 2009
    Posts:
    427
    Hey there, we've got a brutal memory problem I'm trying to track down.

    Observe the following screen shot:

    upload_2022-12-8_15-15-36.png

    We start in the main menu, head in game, and then return to the main menu. in that process there is ~800MB that weren't there before. also, as you can see, the vast majority of this shows up as "Reserved" whatever that means and does not show up in the Tree view or Memory Breakdown, which makes it basically impossible to debug.

    Is there any way to make sense of this??
     
    idyakonov and alexeyzakharov like this.
  2. alexeyzakharov

    alexeyzakharov

    Unity Technologies

    Joined:
    Jul 2, 2014
    Posts:
    505
    Hi @hypnoslave !

    "Reserved" highlights the memory that was allocated from the operating system for Unity's native memory management system.

    Unity memory management uses pooling system for native allocations. We allocate a relatively large sequence of pages of 4-32MB in total size and then serve smaller allocations for different subsystems (e.g. Unity objects).
    The "reserved" part itself is the difference between total pool size and what is actually used by Unity's native memory manager.

    We are planning to add more insights in the All of Memory view to the Reserved node in the next Memory Profiler release, however we do also have reservations as this may be not really actionable and hidden by default. (There could be a possibility of using https://docs.unity3d.com/Manual/memory-allocator-customization.html to play with the "reserved" overhead, although it is a game of memory vs performance overhead).

    Hope that clarifies what reserved part means.
     
  3. hypnoslave

    hypnoslave

    Joined:
    Sep 8, 2009
    Posts:
    427
    interesting, thank you very much for taking the time to reply.

    It appeared that we were running into an out of memory crash on... a platform we were developing for... but it didn't appear that the "used" portion was capping out. However I might have been confused.

    What if Unity has amassed a large amount of reserved memory that it's not using, but even so, tries to reserve more, but can't? Can that theoretically lead to a crash?
     
  4. chemicalcrux

    chemicalcrux

    Joined:
    Mar 16, 2017
    Posts:
    713
    That would be a serious bug!

    If that did happen, it wouldn't necessarily cause a crash: it's not like it needed that memory yet. However, once you start bumping into failure to allocate memory, your program is probably about to die anyway -- something else will need to allocate memory, and it will not be negotiable :p
     
    hypnoslave likes this.
  5. alexeyzakharov

    alexeyzakharov

    Unity Technologies

    Joined:
    Jul 2, 2014
    Posts:
    505
    Yes, it is possible - this problem is known as "memory fragmentation". The allocation and deallocation pattern may result in larger blocks being underutilized and ever growing. It is relevant to both native and managed memory managers.
    Although it maybe relatively hard to crash on platforms where memory is paged, but it will definitely impact performance to some extent.
     
  6. hypnoslave

    hypnoslave

    Joined:
    Sep 8, 2009
    Posts:
    427
    oOOoooh of course! memory fragmentation. it says it has the space reserved, it doesn't say it's all reserved together.

    is there anything I can do on the C# side to .. i dunno. defrag? somehow?
     
  7. MartinTilo

    MartinTilo

    Unity Technologies

    Joined:
    Aug 16, 2017
    Posts:
    2,111
    It's not just fragmentation. If you take a snapshot while you're in game for the first time it probably shows most of that as used. If it reuses most of the space when you go back for a second time after going to the menu, fragmentation isn't your issue either. It is that the in game scene pushed your high water mark up and Unity's allocators are generally greedy because asking for memory is costly, so they will keep the memory reserved, assuming it will likely be reused.

    It can also be that the high water mark is reached at the point of loading a scene, as the memory used for assets used in the previous scene is not unloaded as that scene is unloaded but only on the next unload after that, in case it would be reused in the next scene. Loading an empty scene in-between or calling Resources.UnloadUnusedAssets is a possible way to trade of longer loading times for lower high water marks of memory usage.
     
    Last edited: Dec 17, 2022
  8. hypnoslave

    hypnoslave

    Joined:
    Sep 8, 2009
    Posts:
    427
    that is fascinating. what an interesting idea ... loading an empty scene.

    Thanks Martin, I'll do some tests...
     
  9. mylastggeast

    mylastggeast

    Joined:
    Jun 14, 2021
    Posts:
    47
    Hello @hypnoslave !
    I am facing the same issue described in your OP. I have tried using an empty scene between loads but it did not change much. Did you ever resolve or understand what was going on in the end?

    It's probably worth mentioning that this happens when I load and unload a video from an AssetBundle. I use LoadFromMemory with an Uncompressed Asset Bundle.
     
  10. hypnoslave

    hypnoslave

    Joined:
    Sep 8, 2009
    Posts:
    427
    sorry @mylastggeast , I solved my memory management issues using old-school techniques of crunching down content until I was no longer encountering console crashes. That's it, I'm afraid. I wish I could say I've come out the other side of this process with wisdom, but........ :) newp.
     
    idyakonov and mylastggeast like this.
  11. mylastggeast

    mylastggeast

    Joined:
    Jun 14, 2021
    Posts:
    47
    Thanks for the update!
    On my end, after some investigation, I came to the conclusion that Unity allocates more stuff when it detects newly used classes (eg when I open the video player for the first time?) and reserves memory because of that, but watching the videos over and over has no effect over memory so no leak involved.
    I hope I am right, time will tell!
     
    hypnoslave likes this.
  12. NameString

    NameString

    Joined:
    Mar 23, 2023
    Posts:
    2
    Give an example of C memory allocation. When you use the malloc function, it doesn't actually allocate actual physical memory, it just allocates memory in virtual space. Only after you write to this memory, such as memset operation, the physical memory will be mapped. Something like the code below
    Code (CSharp):
    1. int size = 1024*8;
    2. char* sz = (char*)malloc(size);
    3. memset(sz, 0, size);
    After memset, 8k of physical memory is allocated. Of course, memset is just an example, and any write operation will cause it to allocate physical memory.
    For another example, memset(sz, 0, size/2); At this time, only 4k of physical memory is allocated. The remaining 4k is the reserved part.
     
    MartinTilo likes this.
  13. MartinTilo

    MartinTilo

    Unity Technologies

    Joined:
    Aug 16, 2017
    Posts:
    2,111
    @NameString yes, resident vs allocated memory is another topic related to the question of Reserved memory in so far as that the reserve memory doesn't necessarily have to be resident. In the 1.1.0-exp.1 version of the Memory Profiler we've added the ability to analyze that difference more granularly, and we just released a blog post that goes into more detail on the topic.

    That blog post also provides some tips about analyzing Reserved memory, like
     
    Last edited: Jul 15, 2023
    idyakonov likes this.
  14. wudi_123

    wudi_123

    Joined:
    Oct 8, 2021
    Posts:
    3
    Hello, the "1.1.0-exp.1 version of the Memory Profiler" link can not be found, any update? Thank you!
     
  15. MartinTilo

    MartinTilo

    Unity Technologies

    Joined:
    Aug 16, 2017
    Posts:
    2,111
    Whoops, looks like I pasted the link in there twice and thereby broke it. I've corrected it in the post itself.

    But also, since then, we released version 1.1.0-pre.1. For details on the latest version, you can always check the pinned threads in the Profiler Previews subforum and we do try our best to remember to update this thread as close to the release date as possible, so you can switch on "Watch this thread" for notifications of new version releases.

    Do note that the blog post mentioned above still has a mistake in it in claiming that the more granular per object breakdown of allocated vs resident would be available for captures taken of 2022.2+ versions, that is only available for captures from 2023.1+ versions.
     
    idyakonov likes this.
  16. joshuacwilde

    joshuacwilde

    Joined:
    Feb 4, 2018
    Posts:
    690
    @MartinTilo is memory ever given back to the system? For example if we have a lot during a scene load, but then after the scene loads, the used memory usage goes down. Is this previously reserved memory given back to the OS? Or does Unity keep it allocated for the duration of the game session?

    We have in some cases extremely high reserved values (greater than 250 MB) which on mobile is a massive amount. So we want to know what we can do to improve this.
     
  17. MartinTilo

    MartinTilo

    Unity Technologies

    Joined:
    Aug 16, 2017
    Posts:
    2,111
    It depends. Managed memory may be returned to the OS once a page (usually about 4kb) has been entirely empty for a while (every 6th GC.Collect in the current implementation of the Mono and IL2CPP Boehm GC as of writing. This is an implementation detail that you shouldn't bank on. Also, calling GC.Collect multiple times until you hit that
    GC_CollectsSinceStartup % 6 == 0
    is not helpful and should be avoided. That is, because it will fragment longer contiguous virtual address space that could have been reused even further.)

    Native memory may, depending on the Allocator, also be unloaded but that may be even less predictable to the point where you might as well assume it won't happen.

    That said, different platforms deal with stale memory differently. Such unused memory may end up getting pushed out of Resident memory by getting compressed, moved to swap file/ just unmapped from physical memory until needed again.

    You can go into the Memory Profiler preferences and check the option to see detailed breakdowns for reserved memory. With 2023.1+ and package version 1.1 you can also get per page granularity residency information displayed that may help you identify what of that you actually need to care about, i.e. allocated but non-resident unused reserved memory won't get your app evicted by the OS.