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. Dismiss Notice

Profiler Memory Snapshot, determine who references the RenderTexture

Discussion in 'Editor & General Support' started by IgorAherne, Jun 26, 2017.

  1. IgorAherne

    IgorAherne

    Joined:
    May 15, 2013
    Posts:
    385
    Guys, trying to profile a memory leak in Editor;

    I've made a sample inside of profiler, please have a look:

    profiling the editor.JPG

    Need to know what particular thing is referencing my TempBuffers (or what created it), or who created it in the first place? Perhaps there is an evil asset / unitypackage which did it? We have like 1400 render textures generated in Editor.

    Thank you!
     
  2. Skaarah

    Skaarah

    Joined:
    Aug 2, 2014
    Posts:
    3
    I'm experiencing this same issue only on the scale of over 100,000 TempBuffers. Did you ever figure out what was causing this?
     
  3. IgorAherne

    IgorAherne

    Joined:
    May 15, 2013
    Posts:
    385
    I did notice it happened when Collab (Services panel was opened); But I am not sure... Perhaps it's a problem with something else, but they might have forgotten to release texture memory or smth, generating new texture every frame
     
  4. OneManBandGames

    OneManBandGames

    Joined:
    Dec 7, 2014
    Posts:
    207
    Sorry for reviving this old thread, but still experiencing this issue in Unity 5.6. For me it seems to originate somewhere from the scene view window and the terrains in my game. In play mode with the game window maximized I do only see some of these TempBuffer render textures being created, but they also seem to be released at some point again.

    If I have the scene view visible and start doing stuff like filtering the hierarchy to look for certain Game Objects, I notice those TempBuffer render textures being created en masse and they will persist until I switch projects / close Unity.
    Depending on what I do these can crash Unity or even my entire PC quickly.

    For now I made me a button in Unity that executes the following script to release the RTs again during design time, maybe it is useful for someone:

    Code (CSharp):
    1.  public void ReleaseRT()
    2.     {
    3.         var rendTex = (RenderTexture[])Resources.FindObjectsOfTypeAll(typeof(RenderTexture));
    4.         for (int i = 0; i < rendTex.Length; i++)
    5.         {
    6.             if (rendTex[i].name.StartsWith("TempBuffer"))
    7.             {
    8.                 RenderTexture.ReleaseTemporary(rendTex[i]);
    9.             }
    10.         }
    11.         System.GC.Collect();
    12.     }
     
    IgorAherne likes this.
  5. IgorAherne

    IgorAherne

    Joined:
    May 15, 2013
    Posts:
    385
    Thanks! I've also improved your script, so it does it automatically

    Code (CSharp):
    1. using UnityEngine;
    2.  
    3. #if UNITY_EDITOR
    4. using UnityEditor;
    5. #endif
    6.  
    7. // occasionally releases TempBuffers, which are created through a bug, beloning to Unity.
    8. // Without it, unity can consume a lot of memory, have bad fps in editor & even crash.
    9. //
    10. // Authors:  OneManBandGames,  Igor Aherne
    11. // https://forum.unity.com/threads/profiler-memory-snapshot-determine-who-references-the-rendertexture.479704/#post-3363255
    12. [InitializeOnLoad]
    13. public static class AutoReleaseUnityRenderTargets{
    14.  
    15. #if UNITY_EDITOR
    16.    
    17.     static double _flushIntervals = 90;//every 90 seconds, or tweak to do less often (involves garbage collection)
    18.     static double _lastTime = 0;
    19.  
    20.     //ran via [InitializeOnLoad]
    21.     static AutoReleaseUnityRenderTargets() {
    22.         EditorApplication.update -= OnEditorUpdate;
    23.         EditorApplication.update += OnEditorUpdate;
    24.     }
    25.  
    26.  
    27.  
    28.     [UnityEditor.Callbacks.DidReloadScripts]
    29.     public static void OnCompiled() {
    30.         EditorApplication.update -= OnEditorUpdate;
    31.         EditorApplication.update += OnEditorUpdate;
    32.     }
    33.  
    34.  
    35.     static void OnEditorUpdate() {
    36.        
    37.         if(EditorApplication.timeSinceStartup < _lastTime + _flushIntervals) {
    38.             return;
    39.         }
    40.         _lastTime = EditorApplication.timeSinceStartup;
    41.  
    42.         //release the bugged textures:
    43.         var rendTex = (RenderTexture[])Resources.FindObjectsOfTypeAll(typeof(RenderTexture));
    44.         for (int i = 0; i < rendTex.Length; i++)
    45.         {
    46.             if (rendTex[i].name.StartsWith("TempBuffer"))
    47.             {
    48.                 RenderTexture.ReleaseTemporary(rendTex[i]);
    49.             }
    50.         }
    51.         System.GC.Collect();
    52.     }
    53.  
    54. #endif
    55. }
    56.  
     
    Last edited: Jun 27, 2018
    OneManBandGames likes this.
  6. OneManBandGames

    OneManBandGames

    Joined:
    Dec 7, 2014
    Posts:
    207
    Thanks, excellent idea! Replaced my shady button with your improved version. ;)
     
  7. fherbst

    fherbst

    Joined:
    Jun 24, 2012
    Posts:
    801
    For future Google searches ending up here (same as me with the same issue):

    Most likely this issue is caused by calling RenderTexture.GetTemporary without a matching RenderTexture.ReleaseTemporary. Either from your code or from a rogue package. You'll find out by opening visual studio and exploring all found calls to RenderTexture.GetTemporary.

    Took me a while to figure this out - while most parts of Unity are fully managed (meaning you don't need to think about releasing resources) this one isn't.
     
    OneManBandGames and IgorAherne like this.
  8. IgorAherne

    IgorAherne

    Joined:
    May 15, 2013
    Posts:
    385
    Omfg!!
     
  9. OneManBandGames

    OneManBandGames

    Joined:
    Dec 7, 2014
    Posts:
    207
    Thanks for posting the solution for this! I searched across my project and I found some calls from all kinds of packages & Unity Standard Assets and I from first glance it looked like all would call ReleaseTemporary at some point, so not sure what caused my issue. Then again I'm not sure if it even is present in my project anymore, I did not experience the issue for quite some time now even with the script workaround from above disabled.
    I could imagine that it was a bug in some of the packages that caused it, and it "updated itself out" in the meantime.
    The good thing is with your info I'm confident that I will be able to track it down now if it hits me again, so thanks again for the update!
     
    IgorAherne likes this.
  10. Peter77

    Peter77

    QA Jesus

    Joined:
    Jun 12, 2013
    Posts:
    6,444
    You might be able do this with either of these free tools:

    Heap Explorer
    https://forum.unity.com/threads/wip...filer-debugger-and-analyzer-for-unity.527949/

    Memory Profiler
    https://bitbucket.org/Unity-Technologies/memoryprofiler

    Both tools allow to inspect which objects hold a reference to a particular other object. Here is how you would try to find this in Heap Explorer:
    • In Heap Explorer, click "Capture & Analyze"
    • Open the "C++ Objects" view
    • Find the leaking render textures
    • Select one of these RenderTexture objects
    • It now should display a list of other objects that reference it
     
    IgorAherne and OneManBandGames like this.