Unity heavy GC allocation on Render
See original GitHub issueQuestion
I’am try to loading just 4kb .gp5 file, which results in output .png 96kb.
My setup
var settings = new Settings(); settings.Core.Engine = "skia"; settings.Core.LogLevel = LogLevel.None; Score score = ScoreLoader.LoadScoreFromBytes(Encoding.ASCII.GetBytes(testTab), settings);
LoadScoreFromBytes() https://i.imgur.com/LObmSWy.png As you can see, logger was not deactivated + additional GC
RenderTracks() https://i.imgur.com/NXIGgti.png 2mb GC.
1)Does it possible to disable logging at all? 2)Does it possible to reduce GC allocation? 3)Does it possible to run this in the separate thread? Seems, yes. 4)Does it possible to omit description(name, tuning, bpm) in rendered file?
Your environment (if applicable)
- Version used: .net master
- Platform used: Unity 2019.2, C#
- Rendering engine used: SVG
- Operating System and version (desktop or mobile): Windows 10
Issue Analytics
- State:
- Created 3 years ago
- Comments:8 (5 by maintainers)
Top Results From Across the Web
Garbage collection best practices - Unity - Manual
This section outlines some common issues and workflows that affect when your application triggers the garbage collector. Temporary allocations; Reusable object ...
Read more >Unity Profiler doesnt show where the GC allocations are ...
When I look at the memory overview, it says that GC allocations per frame are as low as 300 and as high as...
Read more >Basics of Optimization in Unity - Ali Emre Onur - Medium
Let's initialize a color variable with new keyword and run the Unity Profiler to observe the allocated space on the GC.
Read more >Unity Tips | Part 1 - Garbage Collection - Daniel Ilett
As you've probably worked out, Instantiate allocates memory resources to bring the object into the game and Destroy removes them from memory – ......
Read more >Slow rendering - Android Developers
If your app suffers from slow UI rendering, then the system is forced ... of allocation can mean more CPU resources spent on...
Read more >Top Related Medium Post
No results found
Top Related StackOverflow Question
No results found
Troubleshoot Live Code
Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start FreeTop Related Reddit Thread
No results found
Top Related Hackernoon Post
No results found
Top Related Tweet
No results found
Top Related Dev.to Post
No results found
Top Related Hashnode Post
No results found
Top GitHub Comments
Sorry, my bad with providing the wrong the namespace.
Lets dissect this number to clarify where these sizes come from.
The main DLL of alphaTab is 4.48MB. This includes the alphaTab code a 3.31MB soundfont and a 632KB TTF Font for the symbols. So the actual code of alphaTab takes up 0.54MB. So the .net version of alphaTab takes 0.54MB while the minimized JS version needs 1.07MB. The JS version still loads the SoundFont and WebFont into the memory of the browser making the JS version 0.5MB less efficient than the .net version.
So let’s talk about possible optimizations:
alphaTab DLL The TTF font is mandatory to do any kind of rendering so the minimum of the alphaTab core library is still 1.16MB. I can take it up for the upcoming TypeScript based version to move the SoundFont from the core library to the windows specific control library. Giving you 1.16MB for alphaTab.
alphaTab is currently not using all glyphs from the font, so theoretically we could try to minimize the font to only contain the symbols used making an alphaTab optimized Bravura font. There are 3227 glyphs in the font and alphaTab is using 93 of them😅. Assuming an equal number of KB per symbol, the font could be shrinked to 18KB (20KB more realisticly). This would result in 0.54MB for the core library. Feel free to open a dedicated feature request for this optimization.
SkiaSharp
You are using Unity, and Unity does not provide any built-in mechanism to render images so it must rely on a 3rd party library to do this Job.
You can ask over at the SkiaSharp repo if there are better ways to minimize the size of the library but we do not have much control over that: https://github.com/mono/SkiaSharp
If you find a more lightweight library for rendering images on Unity, feel free to open a feature request to provide a rendering backend for it.
This is more a question to SkiaSharp and the documentation there. In general: yes it is possible to get the raw bytes and raw pixel colors.
You have to consider that having a final PNG encoded has a lot of raw image processing inbetween. This raw image processing is done on Bitmap base and will need corresponding memory.
As you’re using the low level APIs you will need to set
Logger.LogLevel
instead the setting on the main settings object. Normally the API object takes over the responsibility to initialize the internal logger.Even though the log level is part of the settings object, it is actually still a global setting within alphaTab and not “per-call”.
Still it is quite surprising that the memory allocation is supposed to be so heavy there. Can you see on the deeper nodes of the memory trace what exactly is causing these allocates?
What do you mean by “GC allocation”? alphaTab needs to create an object graph for the data model and the rendering tree. There is no way of reducing the memory actually needed for this operation. In your case where you are maybe just doing a one time PNG conversion this might be an overhead but normally alphaTab is more long-lived as control. You might use the score model to also fill some other UI elements. The rendering pipeline is reusable for resizing of the UI.
If you convert a Score to PNG and scrap the whole objects the GC will simply need to cleanup all of this. Every symbol alphaTab renders is an object to reposition and re-render it in case of resizing.
Yes it is possible. The normal UI controls already off-load the whole rendering process to a background thread. As you are using the
ScoreRenderer
directly you will need to move it to a thread on your own which should be easily possible. Once alphaTab completes the rendering and hands over the finalSkImage
it will not access this image anymore. No need for thread synchronization on this object.This is documented here: https://docs.alphatab.net/develop/reference/property/