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. We have updated the language to the Editor Terms based on feedback from our employees and community. Learn more.
    Dismiss Notice
  3. Join us on November 16th, 2023, between 1 pm and 9 pm CET for Ask the Experts Online on Discord and on Unity Discussions.
    Dismiss Notice

Question Unity UI Memory Allocation from Sprites

Discussion in 'Scripting' started by theVirtunaut, Dec 3, 2022.

  1. theVirtunaut

    theVirtunaut

    Joined:
    Sep 28, 2013
    Posts:
    10
    Hello. I have a pretty simple scene set up: there is a Unity UI Canvas that has multiple children with Image components. It's designed so that when I hit a button, all the Images will choose new sprites from an image manager. The image manager has a list of Scriptable objects called Displays that each have references to some number of sprites.

    When profiling, I can see that after each generation my Texture memory continues to go up. At any time, there are only a small handful of images visible. If I run this enough, Unity crashes trying to allocate memory with 16 alignment.

    How can I use script to manually clear out my texture memory?

    Ive tried both
    Code (CSharp):
    1. System.GC.Collect();
    2. Resources.UnloadUnusedAssets();
    with no luck.
    Looking for advice. Thank you. o_O
     
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    36,814
    Are you new-ing anything up, or creating sprites or creating textures?

    If so you generally gotta Destroy() Unity things, and obviously not hang onto references to them.

    Years ago I grabbed an FPS script off somewhere on the interwebs and because I was a nub I failed to notice that it had a
    style = new GUIStyle()
    call right within OnGUI() so it eventually leaked and blew.
     
  3. theVirtunaut

    theVirtunaut

    Joined:
    Sep 28, 2013
    Posts:
    10

    Nah. I have a non-monobehavior that has a new one created every generation. But it's stored in a single variable that I would assume Garbage Collection handles. When I use the profiler, it really is all the PNG images taking up texture memory.
     
  4. Nad_B

    Nad_B

    Joined:
    Aug 1, 2021
    Posts:
    345
    Well the thing is, while your C# class gets GC'd, any references to Unity objects in it won't. Remember: Unity objects are just wrappers around C++ objects, and to the GC, those objects do not exist at all (i.e. unmanaged)

    So you must have a Destroy() method in your class (or make your class implements the standard C# IDisposable interface) that takes care of destroying all Unity objects, which gets called when the class is no longer needed.
     
  5. theVirtunaut

    theVirtunaut

    Joined:
    Sep 28, 2013
    Posts:
    10
    Thanks for the feedback, guys. I actually refactored my code. The image shows the system I had before, and, after drawing it out, it became obvious why things werent getting released from memory, even tho it seems like the sprite references COULD have been removed.

    I have moved all my high res imagery into Resources folders, and what I have now is a list of names that will Resources.Load<T>() them for as long as i need and then Resources.UnloadUnusedAssets() when I dont need them again.

    upload_2022-12-4_18-47-13.png