Showing posts with label Memory. Show all posts
Showing posts with label Memory. Show all posts

Wednesday, June 3, 2015

Developing for Android, II - The Rules: Memory

The second post from our lovely Android Developers at google is entitled : Developing for Android, II The Rules: Memory

tl;dr - Don't do this crap! (mostly) - Use of memory in an application can be the single most performance modifier. Major topics are listed below.
- Avoid Allocations in Inner Loops
- Avoid Allocations when Possible
- Avoid Iterators
- Avoid Enums
- Avoid Frameworks & Libraries not written for Mobile
- Avoid Static Leaks
- Avoid Finalizers
- Avoid Excess Static Initialization
- Trim Caches on Demand
- Use isLowRamDevice
- Avoid Requesting a Large Heap
- Avoid Running Services Longer than Necessary
- Optimize for Code Size


This article covers various topics from the amount of memory that is consumed to how much memory churn (causing garbage collection - gc) can have an effect on runtime performance. Some of these items seem like poor java coding, but they end up improving the performance. Some trade offs will need to be made in performance vs. code cleanliness. Here Some basic things that came out of the article, if any of these look interesting or 'wrong' go read the article, it will clear some things up :
> Don't allocate new objects during onDraw()
> Use a cached object (avoid allocations in inner loops)
> Static objects in android are static to the process, but maybe multiple activities in the process.
> If using object pools, consider different configurations for lower end devices based on api checks / isLowRamDevice()
> Arrays / Array lists that don't need to be resized often are a good choice.
> Consider using ArrayMap / SimpleArrayMap vs. HashMap, these are more optimized than HashMap, and support iterating over entries w/out iterator.
> Consider setting an initial size of collection to avoid automatic resizing as it grows
> Consider mutating objects vs returning them (which creates new allocations)
> Avoid object types when primatives will do.
> You can use SparseIntArray and SparseLongArray that use primatives.
> Avoid Arrays of objects - eg: instead of Point[]  have a int[] x and int[] y.
> Avoid Iterators - explicit (List.iterator() or implicit for (Object o: myObjects) )
> Avoid Enums.
> Avoid Frameworks / Libraries not written for mobile : these can cause increased memory use & gc
> Avoid Static Leaks : Avoid using where objects should not persist over life of process (lifetime of static variable != lifetime of activity)
> Avoid Finalizers : should ONLY be used when object holds a native pointer.
> Avoid Excess Static Initialization : lazy load when you need it
> Trim Caches : using with bitmaps in a LruCache
> Use isLowRamDevice : disable / enable memory intensive features based on device memory
> Avoid Requesting a Large Heap : Using this as first step for memory management will impact the device and overall user experience vs fixing the underlying issues.
> Avoid Running Services Longer than Necessary : If you don't need a service, shut it down. There are androidy ways to spool it back up.
> Optimize for Code Size : Less code to load, faster to download and run.. Use Proguard (or dexGuard), be cautious in your library usage, understand auto gen code cost, favor simple direct solutions vs creating lots of infrastructure and abstractions.