Open Sesu8642 opened 2 days ago
I've started to look into this. It's weird. I see 160 bytes used per character in the String, when displayed in a Label. Label does seem to be using more than it should be using, since I compared with TextraTypist's TextraLabel class (which does a lot more out-of-the-box), and even TextraLabel is using about 1/6 the memory of what Label uses. I'm thinking it may boil down to simply being a lot of vertices to store and display, but 6x as many for Label seems odd.
The first thing that comes to mind to resolve this for your purposes would be to put Labels on separate pages (as if they were an actual printed legal document), and only load a Label for the current page at a time.
Pagination, culling off-screen lines (maybe don't even read the whole file in at once), using a library, a native dialogue, opening the licence info in an external app... lots of solutions. In fact, I am certain you have far more licence text than you are legally required to include, but to be honest I'd rather not get into the nitty gritty of it. Just because I can point to endless apps and games that don't display megabytes of licence info no-one will ever read, that's not to say they're in the right for it.
But I do think this should be investigated, see if all the bytes it uses are truly necessary.
Thanks for looking into this so quickly! Since I already have the license texts organized in a directory structure, I will probably use that to generate a similarly structured UI.
I'm glad you agree that there is an underlying issue that deserves investigating.
So the heap measurement seems too high, and higher than the actual amount of memory used. I tried using a different way, measuring only the Label or TextraLabel, and anything it has as a member variable. The commit where I added this measurement is here. I'm still (surprisingly) seeing more memory used by Label than TextraLabel, but not by much... ThreadMXBean reports 284,068,160 bytes used for Label, or 208,281,760 bytes for TextraLabel, on the same 10,000,000 character string.
TextraLabel I'm more familiar with internally, since I wrote all of it, and I know it needs at least 8 bytes for every displayed glyph (containing 32 bits of per-glyph RGBA8888 color, 16 bits of style information, and 16 bits of UTF-16 char). Taking about 20 bytes per glyph isn't a huge step past that, since this particular piece of text has a lot of lines, and my code has each Line as its own object.
Label I'm less familiar with, but I know it organizes text into runs, and I think each run is its own object. I also think a line break will break a run up. That means a million runs, one per line.
So far, neither of these explains where all 200+ MB are actually going... Thankfully, we now know it isn't more than a gigabyte being used by Label (more than a quarter-gigabyte, but still).
Issue details
In my game, I display the license texts of the free / open source dependencies. To do so, I currently use a label inside a scroll pane. The size of the license texts is quite large, around 3.7 MB. As soon as i show the screen, the RAM usage increases by several 100 MB and causes an OutOfMemoryError on Android devices. I also tried using a TextArea which has the same issue but to a lesser extend.
Reproduction steps/code
In this minimal example, the ram usage increases from around 100 MB to 1.8GB despite the text content itself only being 10 MB.
demo.zip
Version of libGDX and/or relevant dependencies
tested with libGDX 1.13.0 and 1.12.1
Stacktrace
Please select the affected platforms
(others are likely affected too)