Search Unity

TMP_CharacterInfo size in memory gets gigantic on iOS

Discussion in 'UGUI & TextMesh Pro' started by bigbrainz, Aug 14, 2020.

  1. bigbrainz

    bigbrainz

    Joined:
    Jul 21, 2015
    Posts:
    177
    Howdy!

    We're trying to get the iOS version of our app to not run out of memory. One thing we're finding is that over time the TMP_CharacterInfo size gets really huge. Over 111MB and counting (6,000 objects).

    TextMeshProUGUI also adds 33MB and WordWrapState tack on 32MB. Altogether it's a killer.

    Could you please share any thoughts or tips on what we can do to release all those from memory? We're running garbage collection pretty consistently, but these guys are still staying stuck. We're running 2019.4.8f1 and TMP 2.1.1.

    Thanks!
     
  2. Stephan_B

    Stephan_B

    Joined:
    Feb 26, 2017
    Posts:
    6,595
    Currently, the text parser and layout is owned by each text object. This includes the textInfo which as you point out becomes increasingly memory intensive with growing number of text objects.

    This is something that I am well aware of and currently planning on changing in TextCore which will be the new text parsing and layout engine used by TMP, UI Toolkit, and Unity in general. No firm ETA on that yet.

    In the meantime, I have the following question.

    Are you text objects mostly static? Ie. Once instantiated, does the text change?
     
  3. FlyingOreos

    FlyingOreos

    Joined:
    Mar 24, 2014
    Posts:
    12
    Hi Stephan,

    We're in a similar situation with TMP components and WordWrapStates eating a lot of memory (around 16.5 KB each). With a lot of text components in the game, this quickly adds up.
    We were wondering where you are going with the "text objects mostly static" question? Are there any optimizations at all we can do to get rid of the WordWrapState allocations? Turning off word wrapping doesn't appear to help at all.
     
    Last edited: Sep 4, 2020
  4. bigbrainz

    bigbrainz

    Joined:
    Jul 21, 2015
    Posts:
    177
    Once instantiated our text is mostly static.
     
  5. Stephan_B

    Stephan_B

    Joined:
    Feb 26, 2017
    Posts:
    6,595
    I am currently testing a change where users will be able to set some flag on the text object that will results in the disposing of most of the data structures used in the text parsing and layout process.

    This will reset the allocations of individual text objects back to those of a newly created text object where it remains in a state where it can still be updated but at the cost of reallocating those buffers.

    This should result in significant reduction of the overall memory footprint for those text objects using this new flag.

    For instance, a text object that contains 31,718 character ends up allocating a characterInfo[] that takes 11.4mb. With the change this same data structure will take 3.0kb.

    I will post more detailed information later tonight / over the next few days.
     
    bigbrainz and TheoKiloo like this.
  6. bigbrainz

    bigbrainz

    Joined:
    Jul 21, 2015
    Posts:
    177
    Ah, that should be very helpful, thank you and good luck!
     
  7. Prodigga

    Prodigga

    Joined:
    Apr 13, 2011
    Posts:
    1,123
    We're encountering this issue, any follow up?
    upload_2020-9-23_16-59-57.png
     
  8. TheoKiloo

    TheoKiloo

    Joined:
    Dec 5, 2016
    Posts:
    10
    As a quickfix while waiting for the optimization possibility mentioned above, we've located a simple change that eliminates the massive TMPro.WordWrapState[] allocations.

    In TMP_Text.cs, make the 'm_EllipsisInsertionCandidateStack' static:
    upload_2020-9-23_23-36-23.png

    As far as I can tell, this stack is always cleared before use, so it should not have any impact on functionality.

    Before:
    upload_2020-9-23_23-33-31.png

    After:
    upload_2020-9-23_23-33-39.png

    Unfortunately, this does mean that we've had to copy the source files of the TMP package into our project as we were otherwise unable to modify the source.
     
    Prodigga likes this.
  9. bigbrainz

    bigbrainz

    Joined:
    Jul 21, 2015
    Posts:
    177
    Stephan!

    Hey, I don't suppose you have any kind of udpate you can share on this. The RAM usage is really a critical issue for a lot of our users.

    Thank you!
     
  10. Stephan_B

    Stephan_B

    Joined:
    Feb 26, 2017
    Posts:
    6,595
    You should already be seeing some improvements in the latest release with regards to WordWrapState, MaterialReference and other data structures used in the parsing and layout of the text.

    In the next preview release, there will be additional improvements. This time dealing with the textInfo and sub data structures like characterInfo, etc.
     
  11. bigbrainz

    bigbrainz

    Joined:
    Jul 21, 2015
    Posts:
    177
    Sounds good. We've held off on grabbing the new update because the last time we updated it caused huge problems for us everywhere, but if there are some key fixes in this new version we'll grab it. We're currently on 2.1.1, but I see that there's a "verified" 2.1.3. I assume that's what you recommend for URP, 2019.4. Thank you!
     
  12. Stephan_B

    Stephan_B

    Joined:
    Feb 26, 2017
    Posts:
    6,595
    Indeed version 2.1.3 is the recommended release for 2019.4.
     
  13. bigbrainz

    bigbrainz

    Joined:
    Jul 21, 2015
    Posts:
    177
    Stephan,

    I finally got back to measuring the fantastic improvement the update brought. With the update, TextMeshProUGUI has shrunk from 33MB down to 8.4MB. And I can't even find WordWrapState anymore, which used to add 32MB. That's a GREAT improvement. Nice work!

    TMPro.TMP_CharacterInfo is still painfully big--100MB. It sounds like that's exactly what you're working on right now, so good luck--we can't wait! In the meantime, if there's anything we can do now manually to clear that or reduce it or anything, please let us know.

    Thank you!

    upload_2021-1-14_15-36-14.png
     
    Prodigga likes this.
  14. tessellation

    tessellation

    Joined:
    Aug 11, 2015
    Posts:
    390
    Hi, @Stephan_B - reviving this thread because I too have been doing some memory profiling and I'm finding that these TMP-related types are building up over time as the user visits various UI screens. Mostly CharacterInfo arrays (8MB) and TMP UI Meshes (2MB).

    It feels like these things should go away, for certain objects, once the TMP object is disabled. A flag in "Extras" to clear these things seems like a reasonable idea or maybe the static flag could be used. I need to think about that one.

    Also what's TMP_HighlightState[16]? - there seems to be one for every TMP_Text in the game (300KB), but does that need to be allocated for non-InputField texts?

    For now, is there a recommended way to forcefully cause a TMP_Text component to flush it's cached data?
     
  15. CChong_at_Infinity

    CChong_at_Infinity

    Joined:
    Apr 7, 2020
    Posts:
    27
    Hi,

    Sorry to necro this thread, but is there a fix for the TMP_CharacterInfo memory issue coming? We are still getting this as of Unity 2020.3.26f1 and TMP 3.0.6.
     
    Tetsuya_OYA and Prodigga like this.
  16. tessellation

    tessellation

    Joined:
    Aug 11, 2015
    Posts:
    390
    Hi, @Stephan_B We're still looking for a way to force release the TMP_CharacterInfo and other cached data that can be dynamically released when a screen or dialog box is hidden. These things accumulate over time and it doesn't seem necessary to keep around all this cached data for transient text.
     
  17. Stephan_B

    Stephan_B

    Joined:
    Feb 26, 2017
    Posts:
    6,595
    This is something that I am planning on addressing where users will be able to control whether or not the TextInfo and its content which includes the CharacterInfo will be persistent per text label. This should result in a significant memory overhead reduction overall.

    I am still working on full support for OpenType Layout features along with support for Color Glyphs (Native Emojis) but once I am out of this OpenType hell, I will be working on text parser and layout improvements which will include the above memory overhead improvements amongst lots of other goodies.
     
  18. tessellation

    tessellation

    Joined:
    Aug 11, 2015
    Posts:
    390
    This will be very helpful. Looking forward to that, thanks @Stephan_B !

    Wow that Opentype stuff does sound really complicated and probably hellish as well, but very useful for certain language scripts, I can imagine.

    One of the TMP layout features you might consider for games is a balanced wrapping for regions where the text is inside of a dynamic (ContentSizeFitter) shape. For example a chat or character dialog bubble. I also do this with popup tutorial text. So let me give you an example line of text:

    This is important text as an example of word wrapping.​

    Now let's say we can wrap this text onto a second line and we have a maximum width of approximately 8 words (for lack of a RectTransform width here), then we'd get this:

    This is important text as an example of word
    wrapping.​

    This doesn't look so great in a dialog or tutorial bubble, especially if the last word is very short. What would be better is if we say that as long as it's on two lines, then try to balance the width of those two lines like so:

    This is important text as an
    example of word wrapping.​

    I have a custom script that does this where it sees if there's any wrapping and then it dynamically shrinks the RectTransform width by some step size and then regenerates the text each step until it's gone onto a third line and then goes back one step. The works, but costs a lot of CPU to regenerate the text mesh so many times. I can send you the script if you're interested.

    Anyway, I just thought this would be a very nice built-in feature to have for games and your version would no doubt be much cheaper to compute than my hacky script.
     
    Stephan_B likes this.