JUCE 7 AUv3: high memory pressure in Logic Pro on iOS

We’re starting to receive customer reports that certain JUCE 7.0.12 AUv3 plugin instances won’t load in Logic Pro on iOS. The Logic projects are typically quite complex with dozens of plugin instances across several tracks.

After a bit of debugging, this is what we found:

  • When loading a project, Logic creates all editors of all JUCE plugins even if they are not shown or opened, and initially does so with a large size (1194 x 834 editor logical pixel size on our test device)

  • JUCE/Metal allocates a significant amount of (buffer) memory for UI rendering

  • It is this UI-related buffer memory that is by far the largest contributor to memory pressure in our plugin, initially causing AudioProcessor::memoryWarningReceived() callbacks, followed by Logic reporting that subsequent instances won’t load as a result of malloc failures.

  • Reducing the UI size after loading a project by opening the editor and resizing it substantially reduces memory footprint immediately but this doesn’t solve the issue when loading a Logic Pro project where all plugins are initially instantiated with a very large UI while not being visible at all.

Has anyone encountered this, or perhaps know a solution how to reduce memory pressure when a plugin is not yet opened in Logic Pro on iOS? We’ve reduced memory usage of the Components within the plugin as much as we can.

The way to trigger the issue is to create a track, add 5 or more of the same (resizable) plugin on that track, and subsequently duplicate that track 10 times. Then save the project, and re-open it, browse through the tracks and their effects, and at some point you’ll probably start to see error messages.

You can address that in your own code.

  1. Make all the contents of your editor wrapped in a std::unique_ptr<Component>
  2. Only create the contents on visibilityChanged when the editor is visible, and destroy it otherwise.

Other than that, there are many things you can do in your plugin code to improve multi instance performance, for example creating singletons for shared images, shared fonts… etc.

Thanks for the tips! We’ve implemented most of these already. Doesn’t really solve the issue what we’re raising here though. Even an empty JUCE app with a blank editor has a significant memory footprint in Logic due to the memory allocated for rendering that empty UI, and this is what we’re trying to git rid of when the UI isn’t visible or was never actually opened.

Yes, I see what you’re saying.

I just tried on my computer and 100 invisible windows with the size of 3000x3000 took about 2gb, while 500x500 took about 500mb with the same settings.

I do think this is overall a Logic bug - the DAW shouldn’t keep all those windows around, but maybe there’s something that can be done on the JUCE side to avoid allocating the memory if a window is invisible.

Thanks for confirming! I agree it’s strange behaviour from Logic to keep all these editors alive.

I was hoping though that with some simple JUCE mods, the graphics buffers could be released when the editor isn’t visible but that’s probably up to the JUCE team to see if this is feasible or not.

It seems the issue predominantly exists in iOS if we set:
JUCE_COREGRAPHICS_RENDER_WITH_MULTIPLE_PAINT_CALLS=1

Without this preprocessor definition, the amount of memory allocated seems much more reasonable…

2 Likes