Opacity zero does not free memory

357
3
02-26-2024 04:44 AM
Status: Open
kris
by
New Contributor III

Hi!

Our app has, say 10 map layers. Our users typically only have a few of them visible, simultaneously, and we have some sliders allowing them to adjust the opacity of each layer. 

While investigating some other issue, we discovered that we do not see any correlation between opacity and consumed memory by the runtime SDK, so we now remove the map layer from the map when the user "disables" the layer by sliding opacity down to zero. 

If we are correct in this, would it be an idea for the runtime to implement this logic?

Cheers

3 Comments
Ting
by Esri Contributor

Hi Kris, I moved your post to the ideas board, as it is more like an idea rather than a question. 🙂

My 2 cents on this idea:

- At this point, since the Runtime SDK for iOS has entered mature support stage, we aren't adding new features to it. It can be reconsidered for the Swift SDK though.

- To me, "changing opacity to zero causes the layer to be deallocated" sounds like an unexpected behavior, rather than a feature. I think it would be better to leave this custom logic to developers to implement.

- This scenario is kind of resembling iOS's removeFromSuperview vs setHidden methods. The former deallocate the view object, whereas the latter just set a flag to not draw the view when the view hierarchy renders. In SwiftUI, this article explains the various ways of hiding a view: hidden(), opacity(_:), or a conditional view. I think our layer behavior is more aligned with the opacity modifier in this case.

Nicholas-Furness

Thanks for the question, @kris.

There are a few more broad-ranging things to consider here:

  • If a layer's opacity is set to zero, then set back to something non-zero, what is the expected behavior? Imagine an app wants to temporarily hide a few layers to help the user focus on a particular operation or workflow. Should the data (or metadata) be unloaded and then reloaded every time? This could be a poor user experience (especially if the network is slow, or the user is paying for bandwidth). Instead you would opt in to that experience by removing the layer and deallocating it. That is, by design, different to merely making the layer invisible and then visible, and gives developers a good set of options.
  • Opacity is a visual property. The layer still participates in the map's layer collection. This has impacts on a number of things (table of contents, loaded metadata, related layers/tables, and so forth). The only way opacity 0 might impact a layer is that it will not be considered during identity (which is a visual/interaction based operation).
  • In addition, layers have a Visible property. They also potentially have visible scale ranges. Both of those control whether a layer is visible in the map and can impact its state in a table of contents/legend, but if a layer is out of visible range it should remain in that ToC, just displayed differently.

There's potential that we could do a better job of considering the Visible property in helping us prioritize removing data from in-memory cache under memory pressure, but even then we wouldn't unload the metadata, and it would be in response to cache pressure heuristics.

Hopefully that helps explain why just setting opacity to 0 doesn't really signify that a layer can be deallocated.

Instead, the recommended approach would be to remove the layer from the Map's layers collection and deallocating it. You'd need to keep track of where in the current layer stack to re-insert if when the user wants to see it again, but we believe that is the best balance when considering the broader picture of layers in a map.

kris
by

Howdy @Nicholas-Furness thanks for your response. 

I agree that the opacity-zero-not-removing-map-layer is a feature, we just noticed it while investigating memory pressure, and we are now removing the layer from the map as soon as the "visibility slider" hits zero. 

On topic memory pressure, do you have any recommendations how to reduce? For older iPads with less RAM, we are able to trigger memory warnings from iPadOS. 

Removing invisible layers helps to some degree, but we're still thinking about how to better control memory usage by the map for the most eager users that enables a large set of map layers. 

Things we have in mind are:
* Merging together raster layers 
* Merging together vector layers
* Reducing number of vector layer data types

Is there anything else than this and removing map layers we should consier when receiving a low memory warning from the OS?

It seems we get these memory warnings more often @ 200 sdk, but that is just a gut feeling.