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 are updating our Terms of Service for all Unity subscription plans, effective October 13, 2022, to create a more streamlined, user-friendly set of terms. Please review them here: unity.com/legal/terms-of-service.
    Dismiss Notice
  3. Have a look at our Games Focus blog post series which will show what Unity is doing for all game developers – now, next year, and in the future.
    Dismiss Notice

Texture memory management should be documented/implemented better

Discussion in 'Scripting' started by ryandjeffares, Aug 15, 2022.

  1. ryandjeffares

    ryandjeffares

    Joined:
    Aug 13, 2020
    Posts:
    6
    Hey all,

    I just have a suggestion surrounding the documentation (or lack thereof) and implementation of memory management with the Texture and Texture2D classes.

    In my current work project (which is more of a UI app than a game), we load png/jpg files from disk a lot to display on the UI. I understand this is a less common use case for Unity, but not unheard of. We have had many problems with the Texture2D class leaking memory due to its implementation and the lack of guidance around having to manually clean up memory.

    Nowhere (AFAIK) in the Unity documentation does it say that one has to call Destroy() on a Texture to clean its memory internally. From my experience it seems that if LoadImage() is called on the same Texture multiple times, the previously held pixel data is not always cleared unless Reinitialize() is called before hand, then Apply(). Maybe even a call to Resources.UnloadUnusedAssets() to be sure.

    This feels like a lot of manual work to manage memory in a managed language. Spelling this out in the documentation would be very helpful, or better yet taking care of it in the implementation.
     
    MeijisIrlnd likes this.
  2. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    28,171
    That's because you're not really using a managed language.

    The C# scripts in Unity are a managed context, but they interoperate with the native engine, which is NOT a managed context.

    It's no different than C# code that operates on physical hardware: you may need to consider lifecycle explicitly.

    Fortunately when you change scenes Unity is pretty good about unloading everything that is no longer referenced.

    If you don't change scenes, then you need to be more aware of what you have allocated.

    The profiler can be of great use here. You can also get some distance out of calling UnloadUnusedAssets after releasing references you no longer need.
     
  3. ryandjeffares

    ryandjeffares

    Joined:
    Aug 13, 2020
    Posts:
    6
    But you are when you're writing C#, and I think it's fair to expect the managed C# API layer to take care of memory or for the native code to do it so the user doesn't have to think about it when they have limited communication to the native code. I just think it's a pit fall for less experienced programmers, especially when it isn't documented and little else in the Unity API requires such attention.
     
  4. Kurt-Dekker

    Kurt-Dekker

    Joined:
    Mar 16, 2013
    Posts:
    28,171
    That's nice to think.

    Now think of this:

    EVERY UnityEngine.Object (and thus EVERY Unity object) has a hidden pointer into the native engine.

    That pointer's target has a lifecycle.

    That lifecycle must be considered.

    Your move. :)
     
  5. ryandjeffares

    ryandjeffares

    Joined:
    Aug 13, 2020
    Posts:
    6
    This isn't an issue of the object not being deallocated, the issue is the Texture instance's held data in the native code not getting deallocated. Obviously I can't see the Unity source code but I just fail to understand how the Texture C++ implementation isn't using RAII to deallocate old data when it is replaced. When I am no longer using a Texture instance in C#, the C# GC will deallocate it - why can't its destructor eventually tell the native code to deallocate its data, without the user having to remember to call Destroy()?
     
  6. Kreshi

    Kreshi

    Joined:
    Jan 12, 2015
    Posts:
    252
    I think a smart pointer Integration/implementation is required on the C++ side to automatically call destroy like suggested. Cleaning up texture memory manually is no problem, but it should be documented to avoid any confusion :).
     
    MeijisIrlnd likes this.
  7. lordofduct

    lordofduct

    Joined:
    Oct 3, 2011
    Posts:
    8,063
    Is this thread intended as feedback to Unity?

    You might want to label it as feedback if that's the case.

    ...

    Or are you looking for suggestions on how to deal with the scenario?
     
  8. ryandjeffares

    ryandjeffares

    Joined:
    Aug 13, 2020
    Posts:
    6
    Yeah, this was my main point - I'm not afraid of manual memory management, I just feel like many people would fall into the trap without the guidance.
     
  9. ryandjeffares

    ryandjeffares

    Joined:
    Aug 13, 2020
    Posts:
    6
    This is feedback, sorry I didn't see how to mark it as such - Thanks!
     
unityunity