Search Unity

  1. Megacity Metro Demo now available. Download now.
    Dismiss Notice
  2. Unity support for visionOS is now available. Learn more in our blog post.
    Dismiss Notice

Moving UGUI panels causing memory leak?

Discussion in 'Scripting' started by twelvethirtyfour, Jul 18, 2017.

  1. twelvethirtyfour

    twelvethirtyfour

    Joined:
    Mar 12, 2012
    Posts:
    25
    Hey guys! I've been googling like crazy for the past day and a half while pulling my hair out trying to solve this one. It took a while to even figure out and narrow where the problem was coming from- approx 30mb per second memory was being added and before I knew it there was like 15 GB being used by Unity. I kept enabling and disabling code and objects for hours until I narrowed it down to the UI panels, and it occurs ONLY when their position or Rect anchorPosition is being accessed and changed. It's just a single panel inside a screenspace canvas, with a textbox attached. I read somewhere that there's leak issues with calling text box updates twice per frame, so to make sure it wasn't somehow being moved twice per update, I limited the movement to once every 10 frames and counted the times it was being called. Nothing has fixed it.

    Anyone have any ideas?

    This is the part that causes the issue no matter what. Also, I didn't realize it until now but it has been happening with every UI panel in the past, just too small to notice before. Now that I have 12+ smaller panels following objects, it is 30+mb every second until I close Unity. This is the update (or lateupdate, didn't matter) that is attached to each panel:

    Code (CSharp):
    1. void Update()
    2. {
    3.     if (objecttofollowTransform != null)
    4.     {
    5.         this.transform.position = Camera.main.WorldToScreenPoint(objecttofollowTransform.position);
    6.     }
    7. }
    Here's a screenshot of the panels floating above where they are supposed to go. Positioning and everything is fine, just cripples FPS and hogs memory like crazy.

     
  2. Brathnann

    Brathnann

    Joined:
    Aug 12, 2014
    Posts:
    7,186
    Well, honestly, you should be using the Unity profiler to get a better grasp of what is going on. This will tell you what sort of stuff is happening that may be creating the problem.

    Also, even Unity suggest that you don't use update on several objects if you can help it, but instead use a manager that runs a single update and calls an "update" type method on all the objects it needs to in a loop.
     
  3. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,294
    Camera.main does a FindObjectWithTag("MainCamera") behind the scenes. It's not the cause of the problem, but you really should not use Camera.main in an Update loop ever. Cache it in Start.


    Other than that, I've got no clue. It's probably not the code you're showing, as WorldToScreenPoint doesn't allocate (nor does setting position). Do as Brathnann says, open the profiler, turn on deep profiling, and sort by "GC Alloc"
     
    Kiwasi likes this.
  4. twelvethirtyfour

    twelvethirtyfour

    Joined:
    Mar 12, 2012
    Posts:
    25
    My camera is usually cached but I was messing with some stuff where I had to keep changing cameras and didn't get around to that yet. It's cached in the UIManager that I have and now I've transferred the code to move the panels into one update loop in there.

    Now as I instantiate the panels (all of the 'planets' are randomly generated) I'm adding them to a list and just foreach'ing through each panel to update the positions. Same problems are occuring.

    Not sure how to really solve this still. Here's the profiler stuff. "Objects" keeps climbing indefinitely but it looks like maybe the TextMeshes are the problem? 1.33GB for 12 text boxes seems like something funky is going on...

    The CPU usage says that it's a ton of "scripts" usage but that literally only happens when I have in the one line of code that updates the positions of the panels. Without that, the game runs at 144+ fps smoothly.

    screenshot2.png screenshot3.png
     
  5. Brathnann

    Brathnann

    Joined:
    Aug 12, 2014
    Posts:
    7,186
    hmm...Are you using Unity's TextMesh or the new TextMeshPro that they have recently acquired and is free on the store now?
     
  6. twelvethirtyfour

    twelvethirtyfour

    Joined:
    Mar 12, 2012
    Posts:
    25
    Just Unity's UGUI Text, I'll go check out TextMeshPro now.

    Edit: Swapped all the UI text's with TextMeshPro. Seems like a cool asset, but didn't change anything. Still cripples FPS and raising memory by about 30-40mb per second. :(

    It's such a simple Panel that this is really confusing me. It's just a panel with two text boxes and a tiny image.

    Edit 2: Just tried to remake the entire canvas / panel / text / everything and same thing. Pulling my hair out over here!
     
    Last edited: Jul 19, 2017
  7. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,294
    Could you make a unitypackage that reproduces it? It's probably a bug, but I could take a peak to see if I can figure something out.
     
  8. twelvethirtyfour

    twelvethirtyfour

    Joined:
    Mar 12, 2012
    Posts:
    25
    So, in the process of making a quick example scene I've discovered that if I don't make the Canvas pixel perfect, the problem doesn't happen as quickly. In my game, it used to be 30mb per second of memory being added. I turned off pixel perfect and it seems to raise "only" 1-2mb per second as long as the game is running. Still kinda a big issue, as within 5-10 minutes of play time that could easily be 1GB.

    I added a unity package with a basic scene where the panels follow a gameobject. With pixel perfect on, memory raises ~10mb per second indefinitely. Without pixel perfect, it seems pretty stable, maybe a tiny increase bit over time.

    Edit: Also, when I deactivate the Canvas in my project while it is running, the 1-2 mb/sec increase disappears and the memory is stable. So strange. So what's left of the problem is still related to the panels. I think now at least I can go back to developing other parts, but I'd still like to get rid of that 2mb/s. The 20-30mb per second just made it impossible to run and test the game as unity would eventually crash.
     

    Attached Files:

    Last edited: Jul 20, 2017
  9. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,294
    Turn off the graphics raycaster. Or, try not holding your mouse over the game window.

    It's hillariously bad, if you have Unity and the task manager open at the same time, and move the mouse over the game window, I see the memory consumed rise by about 100 per tick of the task manager. If I move the mouse away, it ticks back down.

    From the latest Unite, I know that clicking things in the canvas is stupidly slow (they check the mouse position against every RectTransform), but I didn't realize that it leaks memory like this. It's probably visible because you have almost 300 canvases.

    Other interesting thing to note - having the mouse over the window drops the FPS down to 1/4th. That's not as bad as Pixel Perfect, which drops it to 1/10th. Don't use Pixel Perfect, kids!
     
  10. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,294
    Update: Tested again at work, and nothing of the above is correct here - the framerate stays stable, and Unity doesn't eat all of my memory.

    I was going to check if this was an editor-only thing, but it might be a some-computers-only thing? I used 2017.1.0f3 on both computers.
     
  11. JoshuaMcKenzie

    JoshuaMcKenzie

    Joined:
    Jun 20, 2015
    Posts:
    916
    let me ask the simple questions.

    are you setting the Text value every frame? or just when the text is actually changed?
    Is any canvas not using Screenspace overlay? and with its camera field null?

    that was another major issue presented at Unite. if you have a canvas set to screenspace camera or world and have that camera field null... Unity will gladly call Camera.main (which calls GameObject.FindGameObjectsWithTag("main camera")) every frame... for every canvas.
     
  12. Legi2

    Legi2

    Joined:
    Jul 14, 2017
    Posts:
    1
    Hi! I've been going through the latest patch notes and saw the following in the recently release 2017.1p2:
    • (912789) - UI: Fixed memory leaks caused by unreleased Meshs in the UI Profiler.
    Could that be what you've been facing? Would be interesting to see if that solves your issue.
     
  13. tswalk

    tswalk

    Joined:
    Jul 27, 2013
    Posts:
    1,109
    just tested your scene with 5.6.2p4 and not having any issues at all... but dude.. so many panels!.. I decided to add another couple hundred, still no memory leaks though.

    [edit]
    btw, you don't have to have all of them in 'panels'.. you could create an empty GO, assign it a (for example) grid layout group, vertical, or horizontal layout group with UI text objects under it... so you don't have these huge panels all over the place.

    that way too, if you need to put a raycastable on them you might be able to interact with each independently. (just a thought)
     
    Last edited: Aug 3, 2017
  14. tswalk

    tswalk

    Joined:
    Jul 27, 2013
    Posts:
    1,109
    so, just out of curiosity.. I ran an extended test (30 minutes), and did notice an increase in memory usage.

    from ~450MB starting to 740MB used by Unity. Looking at memory in profiler, the assets and scene memory usage did not change at all.. just the "other" from ~440MB start up to .52GB, not a big difference, but after stopping the profiler, and clearing it, there was an immediate drop in system memory usage for Unity back to the starting memory usage of ~450MB (didn't actually write it down).

    so I think, there is a possible leak in profiler.. but doesn't seem to be caused by either canvas, panel, or the UI components.

    just my hunch, but I think that if you compile and run you may not have an issue.. just a guess though.

    [edit]
    or.. could be because so many are being parsed in the foreach... just use a for loop instead against the array length and maybe it will help reduce some GC
     

    Attached Files:

    Last edited: Aug 3, 2017
  15. Baste

    Baste

    Joined:
    Jan 24, 2013
    Posts:
    6,294
    It's easy to check if this is the case.
    @twelvethirtyfour make a build of the game, and profile it from the editor. If it's the profiler that's eating all the memory, the build should show constant memory usage in the control panel, and Unity itself should show the increase.