Your Privacy Matters: We use our own and third-party cookies to improve your experience on our website. By continuing to use the website we understand that you accept their use. Cookie Policy
385
Very large/fast memory leak in sync'd DataChartView
posted

I've found what appears to be a very severe memory leak in the DataChartView component. Something related to bitmap caching or something possibly related to synchronized scrolling. Sample project here:

https://dl.dropboxusercontent.com/u/56947838/MemoryLeak.zip

It manifests when you rotate the device, and with this sample it takes 4-5 rotations before the process runs out of memory.

This is with the public CTP builds, but other builds we're using also exhibit similar problems.

I've replicated on both a real device (Samsung 4.4) and a Genymotion Android 5.x emulator.

Thank you!

Parents
  • 30692
    Offline posted

    Hi Ben,

    It's possible this is not the scenario that we've seen before and it could be an interesting leak related to the sync settings. We'll look into that and see if it is a new scenario. A good way to tell is this. If you rotate the device pretty slowly (maybe try waiting 10 seconds between rotations?) does the issue still occur? If yes, this scenario probably represents some form of actual leak related to the synced charts stuff. However, if slowing the creation/destruction down avoids the scenario, then we have a different non-leak scenario.

    If this is the same issue I've seen before, it isn't actually a leak, per-se, but rather an artifact of some of the more strange ways that Anrdoid deals with bitmap memory. The long and the short of it is, that when your app runs out of heap memory, the Dalvik VM forces a garbage collection to occur. Critically, though, Android bitmap classes do not release their native memory until they are processed by the finalizer queue, not when they are first collected.

    This means that it is a common problem on Android that if an application uses a lot of images and you destroy and create views that contain them, you can wind up with enough partially collected images that an OutOfMemoryException can be thrown, even though none of the offending bitmaps are actually still referenced.

    You can proactively destroy bitmaps with the recycle() method to avoid this.

    But how does that relate to the chart? We need to use multiple layered bitmaps to render the content of the chart. If you have a device with a humongous resolution and the chart is taking up a lot of space, these bitmaps are BIG. However, the standard maximum heap allocation for an Android app is, by default, very small, so you can only have a few sets of these images in memory at a time unless you:

    • Set largeHeap on your android application: http://developer.android.com/guide/topics/manifest/application-element.html#largeHeap
    • Proactively destroy charts when you are "done" with a view containing them. This allows us to proactively destroy the bitmaps contained by the chart.
      • If we wait for reactive mechanisms to tell us you are done with a chart, the DalvikVM may have decided the app is out of memory before they execute.
      • You can signal the chart to proactively destroy its internal content by calling destroy(). You should not continue to use that instance of the chart after doing this.

    Note, with more recent builds (non-public) we have mitigated this issue by removing an unnecessary background layer from the component, meaning each chart takes less memory, but you may still be able to reproduce the issue if you cause views containing the chart to be created and destroyed quickly enough. This way there are more released bitmaps that haven't been finalized than the system can cope with.

    The short version is that if you do either of the above bullets, we think you should be ok, since that is our experience, but definitely let us know if you can still reproduce the issue. Last time we looked into it, it definitely didn't seem like a leak. If it were leaking as bad as bad as your scenario would imply, we wouldn't be able to scroll through every chart sample in our Samples Browser without it crashing, as we do. Rather, if you have a small heap (as you do by default in Android) and are creating new views without proactively destroying the images contained in the old views you can cross a threshold where you have too many released but undestroyed images, and cross the heap limit threshold.

    BTW, the reason you are able to hit this via rotating the device is that the default behavior in and android application is to destroy the layout and recreate on an orientation change. You can modify this behavior and let your app resize its views instead and that would also be a valid way to avoid this scenario.

    Let me know if you have any questions about this.

    -Graham

Reply Children