Search Unity

Question Unloading Addressable Assets?

Discussion in 'Addressables' started by Guendolin, Jul 5, 2020.

  1. Guendolin

    Guendolin

    Joined:
    Dec 6, 2015
    Posts:
    4
    Hi!

    I'm new to addressable assets but I think it looks great. Before I start using them in a big project I wanted to test them out on a small scale and see how they work.

    To keep it short and very general; in the bigger project the use case would be to try to reduce memory usage in one particular heavy scene. The user has an option to see previews of objects before selecting one of them. I'll use addressables to load and unload the objects as the users select between them. Building asset bundles and storing them online would not be used at this time, I would only like to use the load/unload function of the package. The build would contain everything.

    I wrote a script trying this out. A simple thing that loads and unloads textures and sets them to a material. In the addressables event viewer everything seems to be working ok. (except that nothing shows if I don't load anything on start, but that's another question...)

    The problem is that when I run the (editor) memory profiler I get a bit different behavior than I expect. The textures I load don’t seem to be released and still shows up in the memory profiler. I would expect the textures to be released once I released the asset reference.

    On start no texture is loaded - a-ok!

    I press space (load one texture) , one texture in memory - a-ok

    O press space again (swap to a different texture), two textures in memory - ???

    O press space again (swap to a different texture), three textures in memory - ???

    And so on...

    Is this just a quirk of the editor profiler or am I missing some core concept of how addressables work?

    All the textures are in the same addressables group called “Textures”.

    Code (CSharp):
    1. using UnityEngine;
    2. using UnityEngine.AddressableAssets;
    3.  
    4. public class TextureLoader : MonoBehaviour
    5. {
    6.     public Renderer renderer;
    7.     public AssetReferenceTexture[] referenceTextures;
    8.  
    9.     [System.NonSerialized] private AssetReference acticveReference;
    10.     [System.NonSerialized] private int currentIndex;
    11.     [System.NonSerialized] private bool currentlyLoading;
    12.  
    13.     private void Start()
    14.     {
    15.         StepToNextTexture();
    16.     }
    17.  
    18.     void Update()
    19.     {
    20.         if (Input.GetKeyDown(KeyCode.Space))
    21.         {
    22.             StepToNextTexture();
    23.         }
    24.  
    25.         if (Input.GetKeyDown(KeyCode.U))
    26.         {
    27.             Unload();
    28.         }
    29.     }
    30.  
    31.     public async void StepToNextTexture()
    32.     {
    33.         if (currentlyLoading) return;
    34.  
    35.         currentlyLoading = true;
    36.  
    37.         currentIndex = (currentIndex + 1) % referenceTextures.Length;
    38.  
    39.         AssetReference assetReference = referenceTextures[currentIndex];
    40.         Texture texture = await assetReference.LoadAssetAsync<Texture>().Task;
    41.         renderer.material.SetTexture("_MainTex", texture);
    42.  
    43.         acticveReference?.ReleaseAsset();
    44.         acticveReference = assetReference;
    45.  
    46.         currentlyLoading = false;
    47.     }
    48.  
    49.     public void Unload()
    50.     {
    51.         if (currentlyLoading) return;
    52.  
    53.         renderer.material.SetTexture("_MainTex", null);
    54.         if (acticveReference != null)
    55.         {
    56.             acticveReference.ReleaseAsset();
    57.             acticveReference = null;
    58.         }
    59.     }
    60. }
    61.  
     
    Last edited: Jul 5, 2020
  2. Guendolin

    Guendolin

    Joined:
    Dec 6, 2015
    Posts:
    4
    If I figures things out correctly and according to this article it seams like unity unly unloads assets when all off the assets in the bundle have their refernece count to zero. Since I had all my textures in one group, they got into one bundle and was never unloaded, since one of them was in use the whole time. I hope I got this correct. I will investigate further.
     
  3. MartinTilo

    MartinTilo

    Unity Technologies

    Joined:
    Aug 16, 2017
    Posts:
    2,451
    I believe this is not a quirck of the Profiler but of the Memory usage in the Editor (including Play mode), which is, for various reasons, different to that of a Player. The Profiler is just stating it as it is (unless, of course, there's a bug I'm not aware of). Memory Profiling in the Editor is sadly just gonna get you this far. So to see what's really going on, make a build and profile that. That will also mean your memory snapshots aren't going to be littered with Editor Allocations and UI stuff...
     
    N8W1nD likes this.
  4. MartinTilo

    MartinTilo

    Unity Technologies

    Joined:
    Aug 16, 2017
    Posts:
    2,451
    It could also be a genuine issue with the way stuff is loaded and unloaded through Addressables. But as the general workflow advise for the profiling in Unity goes: find issues by profiling on device/build, profile the editor for faster iteration speed and with a grain of salt (a big one for memory usage), check results in a build again.
     
    N8W1nD likes this.
  5. Guendolin

    Guendolin

    Joined:
    Dec 6, 2015
    Posts:
    4
    Thank you for your answer! Maybe "quirk " was a bad word for what I meant; that the profiler in-editor is unreliable for real performance.

    I tried with making a standalone build and profile and the results there were more to what I expected.

    One problem that I have now is that the event viewer does not work in editor if I do not load an asset in the first frame in 2019.4.2 and not at all in 2018.4.24. Any tips for this? (I have set the "send event"-bool in the settings object).
     
  6. MartinTilo

    MartinTilo

    Unity Technologies

    Joined:
    Aug 16, 2017
    Posts:
    2,451
    Yep that's fair. I guess it is kinda similar for memory as it is for timings...

    Are you using the Project Settings/Editor/ Enter Play Mode Settings?
    Maybe check that if these options are on, that you do check Domain Reload.

    That said, I just grabbed that info from another bug report. I have no further info on these workings of Addressables so I'll have to leave this up for someone else to answer, though this sounds like something to report a bug on, as it sounds broken or at the very least confusing/unclear.
     
  7. unity_bill

    unity_bill

    Joined:
    Apr 11, 2017
    Posts:
    1,053
    MartinTilo likes this.
  8. ProtoTerminator

    ProtoTerminator

    Joined:
    Nov 19, 2013
    Posts:
    586
    N8W1nD likes this.
  9. realitygarage

    realitygarage

    Joined:
    Feb 17, 2017
    Posts:
    11
    subtle detail regarding behavior of memory profiler. If the addressable asset (in my case a texture I just imported and made addressable) is still selected in the editor showing up in the inspector, after building/packing, the texture appears in memory in the profiler... because its selected in the editor / inspector - with a ton of references - was a bit confusing :(
     
  10. MartinTilo

    MartinTilo

    Unity Technologies

    Joined:
    Aug 16, 2017
    Posts:
    2,451
    Ah yes, Editor snapshots can not separate between Playmode and Editor memory usage. In an upcoming version, we'll at least highlight that issue a bit more prominently in the UI. The drag and drop nature of the editor helps on so many levels, but not on this one...
     
  11. Thomas-Mountainborn

    Thomas-Mountainborn

    Joined:
    Jun 11, 2015
    Posts:
    501
    I'm using Addressables for the first time because I wanted DLC content that can be loaded/unloaded precisely in-game, but it seems like the design of Addressables makes this impossible? I'd love to know the logic behind having the Addressables.Release() call not actually releasing the asset. Seriously, I don't get it.
     
  12. LuGus-Jan

    LuGus-Jan

    Joined:
    Oct 3, 2016
    Posts:
    179
    It's not impossible. We employ this exact tactic. We have several DLC bundles, which are being tracked using a unique label per DLC bundle. When a player decides to load or unload a DLC bundle (only available in the main menu to not overcomplicate things), the DLC script sends out an event to interested systems to unload assets belonging to this DLC bundle, e.g. a music player that unloads additional DLC music files. After the event, the DLC script assumes all handles on that content has been released, after which it can safely call

    Code (CSharp):
    1.  
    2. // When a DLC catalog is loaded
    3. resourceLocatorHandle = Addressables.LoadContentCatalogAsync(catalogPath);
    4.  
    5. // When a DLC catalog is unloaded
    6. Addressables.RemoveResourceLocator(resourceLocatorHandle.Result);
    7. Addressables.Release(resourceLocatorHandle);
    Not saying this is easy, because it requires quite a bit of state management, but it's perfectly possible.
     
  13. Thomas-Mountainborn

    Thomas-Mountainborn

    Joined:
    Jun 11, 2015
    Posts:
    501
    I'm talking about unloading assets within a bundle while keeping others loaded. The way addressables are designed, it's mandatory to split assets into different bundles to be able to unload them.
     
  14. spiney199

    spiney199

    Joined:
    Feb 11, 2021
    Posts:
    7,851
    Addressables is a high-level wrapper around the somewhat old Asset Bundles system. This restriction always existed with Asset Bundles, so it still exists with Addressables.

    Ideally Unity would've not used Asset Bundles, and built addressables on a more modern system, but here we are.
     
    Thomas-Mountainborn likes this.
  15. Thomas-Mountainborn

    Thomas-Mountainborn

    Joined:
    Jun 11, 2015
    Posts:
    501
    Aha, that explains it. How unfortunate indeed.
     
  16. chabichou

    chabichou

    Joined:
    May 16, 2022
    Posts:
    4
    I thought the "Pack Separately" Bundle Mode for a packed assets group was fixing that problem by loading and unloading separately, am I wrong?