Search Unity

Free up memory using Addressables

Discussion in 'Addressables' started by MarkvDrimmelen, Feb 16, 2021.

  1. MarkvDrimmelen

    MarkvDrimmelen

    Joined:
    Oct 13, 2017
    Posts:
    13
    Hello there,

    I have a few questions regarding freeing up memory using Addressables.

    We are developing an open world game with a lot of buildings and are looking to implement a world streaming solution using Addressables. After giving the Memory Management documentation a good read it became apparent that when we pack our building prefabs together in one addressable group (and therefore one AssetBundle), unloading a single asset from it will not free up any memory. According to the documentation memory is only cleared when the entire AssetBundle is unloaded, which happens when it no longer has any references.
    This honestly feels very limiting, can someone explain why memory can't be freed up when a single asset is unloaded from an AssetBundle? Is this something that could be changed in the future or do we need to look for a workaround?

    People suggest laying out Addressables groups in a way that allows for an entire AssetBundle to be unloaded and suggest the following options:
    • Group prefabs by 'level' so i.e. when you go from level1 to level2 you can completely unload the AssetBundle for level1
      • As we don't have multiple levels, this option is out of the question
    • Group prefabs by 'area' to allow the entire area AssetBundle to be unloaded when moving to another area
      • As our building prefabs are used across the entire world and not just single areas, this isn't really an option for us either

    To our understanding this leaves us with only two other options:
    • Pack all building prefabs into separate AssetBundles by using the 'Pack Separately' option
      • This will free up memory the moment a single building prefab is unloaded because it means an entire AssetBundle will be unloaded
    • Make use of the costly Resources.UnloadUnusedAssets method
      • This will free up memory for all unloaded assets up until the method call
    Perhaps the first option would be the most desired, as this is similar to the behavior we're looking for in the first place (free up memory the moment a single asset is unloaded). Does someone know if this would actually be possible when having a lot of prefabs, or will packing everything separately cause too much overhead?

    How would you go about implementing the costly Resources.UnloadUnusedAssets method without causing frame hiccups? A while ago Unity implemented Incremental Garbage Collection, but sadly this doesn't work for the Resources.UnloadUnusedAssets method. So far the only suitable moment we can think of to call this method would be in a loading screen after the player dies.

    Any help regarding this topic would be highly appreciated.

    Have you developed a good workflow to free up memory using Addressables?
    Are there other options we are missing here?

    Please let me know!
     
    Last edited: Feb 16, 2021
    Leniaal and unity_OSeBXw9aivkTJg like this.
  2. MarkvDrimmelen

    MarkvDrimmelen

    Joined:
    Oct 13, 2017
    Posts:
    13
    Although this might be a more advanced topic, I'm quite surprised nobody has replied. Anyone out there with some knowledge on this?
     
  3. Sinyavtsev

    Sinyavtsev

    Joined:
    Feb 29, 2016
    Posts:
    8
    I faced the same issue. Have you solved it in the end?
     
  4. andymilsom

    andymilsom

    Unity Technologies

    Joined:
    Mar 2, 2016
    Posts:
    294
    We have a page about this here: https://docs.unity3d.com/Packages/c...ryManagement.html#assetbundle-memory-overhead

    Generally use the UnloadUnusedAssets method at times where you can afford the overhead. This is an AsyncOperation so can take a few frames to minimise the impact.

    The problem is that we do not know which assets are no longer needed. As an example, when loading a Prefab, we know what AssetBundles contain any referenced assets but not the Assets themselves. So we could unload the Prefab object, but have no information on the subObjects e.g. Mesh. As such a sweep of the memory is needed to see if there are any references still remaining.

    Unfortunately at this time there is no smooth way to resolve this without the solutions you mentioned, organising Assets into similar load/unload packets, and use UnloadUnusedAssets when necessary.