Search Issue Tracker

By Design

Votes

0

Found in [Package]

1.8.4

Issue ID

TB-212

Regression

No

TimelineAssets can't be removed from the memory when using "Resources.UnloadUnusedAssets"

Package: Timeline

-

How to reproduce:
1. Open project "TimelineAssetLeak.zip"
2. Go to Window > Asset Management > Addressables > Groups
3. Press Build > New Build > Default Build Script
4. In the Editor Menu press Leak > Show Timeline Asset Count
5. Observe the number in the Console window
6. In the Menu press Leak > Unload and GC
7. Repeat 4th and 5th steps

Expected result: Timeline Asset Count is 0
Actual result: Timeline Asset Count is 5

Reproducible with: 1.8.3, 1.8.4 (2021.3.28f1, 2022.3.4f1, 2023.1.3f1, 2023.2.0a21)

Notes from the user:
- Not only TimelineAssets but also the Tracks and Clips on the Timeline won't be removed from the memory
- Projects with a huge amount of Timeline Clips will run out of memory when building

  1. Resolution Note:

    In the attached project there are 5 Timeline Assets, and 2 menu item actions. One outputs the number of loaded Timeline Assets (via Resources.FindObjectsOfTypeAll<TimelineAsset>()), and another that unloads unused resources and tells the Garbage Collector to run.

    Resources.UnloadUnusedAssets() returns a reference to an asynchronous coroutine. In the example code, the call to GC.Collect happens on the next line, so it's unlikely that this coroutine has had a chance to finish. I've done some quick modifications and get a final output of "In memory TimelineAsset count: 0".

    using UnityEditor;
    using UnityEngine;
    using UnityEngine.Timeline;

    public static class DisplayTimelineObjectCount
    {
    [MenuItem("Leak/Show Timeline Asset Count")]
    private static void Display()
    {
    DebugOutput();
    }

    [MenuItem("Leak/Unload And GC")]
    private static void UnloadAndGC()
    {
    AsyncOperation operation = Resources.UnloadUnusedAssets();
    operation.completed += (_) =>
    {
    System.GC.Collect();
    EditorApplication.delayCall += DebugOutput;
    };
    }

    static void DebugOutput()
    {
    var assets = Resources.FindObjectsOfTypeAll<TimelineAsset>();
    Debug.LogWarning($"In memory TimelineAsset count: {assets.Length}");
    foreach (var ta in assets)
    {
    Debug.Log($"Found Asset : {ta.name}");
    }
    }
    }

    If, instead of immediately trying to invoke the GC , you wait for the UnloadUnusedAssets coroutine to complete, you should see all your assets get collected.

Add comment

Log in to post comment

All about bugs

View bugs we have successfully reproduced, and vote for the bugs you want to see fixed most urgently.