Resources.UnloadUnusedAssets cannot unload assets without any references.

 private void Update()
    {
        if (Input.GetKeyDown(KeyCode.K))
        {
            a = Addressables.LoadAssetAsync<TextAsset>("masterMemoryDB1");
            b = Addressables.LoadAssetAsync<TextAsset>("masterMemoryDB2");
        }

        if (Input.GetKeyDown(KeyCode.R))
        {
            Addressables.Release(a);
            Debug.Log("Release A");
        }

        if (Input.GetKeyDown(KeyCode.A))
        {
            Addressables.Release(a.Result);
            Addressables.Release(b.Result);
            Debug.Log("Release AB");
        }

        if (Input.GetKeyDown(KeyCode.U))
        {
            _asyncOperation = Resources.UnloadUnusedAssets();
            _asyncOperation.completed += operation => { Debug.Log("UnloadUnusedAssets complete"); };
        }
    }

When I press K key to load asset A and B, press R key to unload asset a, and the profiler shows that asset a has no references. Call Resources.UnloadUnusedAssets() again, asset A cannot be unloaded.

If I uninstall A and B, the asset can be uninstalled normally.

https://docs.unity3d.com/Packages/com.unity.addressables@1.16/manual/MemoryManagement.html#when-is-memory-cleared

addressables 1.16.16
Unity 2020.3.0f1

If A and B are in the same bundle, that is expected. We’re working on getting better connection tracking between AssetBundles and the Assets they loaded in into the memory Profiler backend. As you noticed, this connection is currently not reported to the Profiler, making it seem as though there would be no reference to it.

It’s also described in the Documentation page you linked to:

Thanks Reply.

AssetBundle can achieve more detailed memory management. Why doesn’t Addressables.Release call Object.Destroy?
I can only build A and B into two bundles? But this way will cause Serialized File Overhead.

           var ab = AssetBundle.LoadFromFile("Ab");
           var a = ab.LoadAsset<TextAsset>("a");
           var b = ab.LoadAsset<TextAsset>("b");
           Object.Destroy(a);

I believe it does. The object is gone. If you had multiple instances of it, they’d be all gone but the native memory associated with the asset is still there because it was loaded into memory as part of the bundle.

Yes, to a degree. Depending on how you load them (i.e. single assets from file or the entire bundle directly into memory) you can control when what gets loaded in, just not that it gets unloaded before the bundle gets unloaded.

If you need this fine grained control on unloading, you need to split the bundles. The serialized file overhead is something that needs to be part of weighing that decision over.

1 Like

I read the document carefully

“You can load an AssetBundle, or its partial contents, but you cannot partially unload an AssetBundle. No Asset in ‘stuff’ will unload until the bundle itself is completely unloaded. The exception to this rule is the engine interface Resources.UnloadUnusedAssets. Executing this method in the above scenario will cause ‘tree’ to unload.”

According to my test case, after loading A and B at the same time, only Release A, calling Resources.UnloadUnusedAssets should be able to unload A.

What did I miss?

3 Likes

Can anyone answer my question?

Thanks in advance

3 Likes

I use version 1.16.19 and use Resources.UnloadUnusedAssets in the above situation and it works normally.

Newer versions such as 1.18x will not work properly.

@MartinTilo @davidla_unity

Hey again,
according to the devs on addressables, nothing affecting this should have changed but it might be a bug. Could you please file a report through Help → Report a Bug in the Editor?

Case 1344093

1 Like

Has QA confirmed the problem or is there any update? @MartinTilo @TreyK-47

It’s been reproduced and you can follow the progress on that bug here Unity Issue Tracker - Memory doesn&#39;t get released when calling Resources.UnloadUnusedAssets

1 Like

Any news on this? It’s marked “Fix In Review for 1.18.14”, but latest version of addressable is 1.19.9.
We found this issue recently and it’s terrible (using 1.19.6), game memory overload after some loading and nothing can be cleared from memory, does there is any workaround?

Edit: After more testing it seem that nothing can be released until all assets have ref count to 0 on a bundle. So what is described in the doc, about Resources.UnloadUnusedAssets is wrong, it don’t force asset to unload, you really have to have zero asset used from a bundle to be able to free memory. That seem mandatory, you better have to think about your bundle organization to be able to unload everything to free memory. At least until UnloadUnusedAssets is fixed.

2 Likes

If this problem is true, then Addressables is a system with a major problem: memory is not unloaded.
I still haven’t heard anything back from them, does that mean they are still investigating?

I found this document, Memory management | Addressables | 1.19.19
In the first place, Why do we need to call Resources.UnloadUnusedAssets() when we are using Addressables?
Isn’t one of the features of Addressables that it can manage memory well as long as the handle is properly Release()?
I thought that moving to Addressables would have the advantage of eliminating the need to call the unusually burdensome Resources.UnloadUnusedAssets(). But reality seems to be different.
Even though ‘Resources’ is officially deprecated, Addressables doesn’t look much different In memory management.

As with Addressables 1.20.3, Resources.UnloadUnusedAssets still cannot free memory of assets in a bundle when any asset in that bundle has a ref count greater than 0. The document seems quite misleading.

Reported a bug,
CASE IN-11667

Hi all I can see that we will need to clarify that example in the docs. But the the key point is “If you release tree, it’s ref-count becomes zero, and the blue bar goes away”. Then the following rules apply: “In this example, the tree asset is not actually unloaded at this point. You can load an AssetBundle, or its partial contents, but you cannot partially unload an AssetBundle
”
https://docs.unity3d.com/Packages/com.unity.addressables@1.20/manual/MemoryManagement.html#understanding-when-memory-is-cleared

AssetBundles (and the assets they contain) are fully unloaded if they have no assets in use (aka the bundle has a ref count of 0). This means that assets “released” through Addressables aren’t unloaded until their bundle can be unloaded.

You can use the Resources.UnloadUnusedAssets to unload these “released” objects, although it’s not recommended. It is a slow operation that can cause frame hitches. This is because it traverses the entire dependency tree to determine if an asset is unused. Additionally if the unloaded asset is loaded again from the same bundle that hasn’t been reloaded, loading the asset fail.

Hey, thank for your reply.

But this is still not true as I wrote in the bug report. You can not truly unload a “released” object by using Resources.UnloadUnusedAssets until its asset bundle itself is also being released, that is, all assets in the bundle has 0 ref-count.

I see @RINNUXEI , we will investigate the ticket. Thank you!

2 Likes

@pillakirsten @MartinTilo Hey, Any updates on this? Addressables is not working as documented (Resources.UnloadUnusedAssets not unloading released assets) for more than 3 years now.

Also “if the unloaded asset is loaded again from the same bundle that hasn’t been reloaded, loading the asset fail” — sounds like a bug (though we can’t verify this because the released assets are not unloaded in the first place).

Unloading released assets from bundle is an essential feature; you can’t really expect each asset to be perfectly distributed between bundles. It doesn’t matter if “Resources.UnloadUnusedAssets” is slow, as this kind of operation is intended for loading phases.

Currently the only workarounds are either using “PackSeparately” which imposes an unacceptable overhead or manually sorting assets between bundles which is time consuming and is not a solution anyway, since not all assets can be split like that.