Skip to content

Instantly share code, notes, and snippets.

@nindalf
Last active August 29, 2015 14:04
Show Gist options
  • Save nindalf/63dffe2525d6087c9cf6 to your computer and use it in GitHub Desktop.
Save nindalf/63dffe2525d6087c9cf6 to your computer and use it in GitHub Desktop.
Android sessions

###Android Memory

To find out how much memory you have available for your app - ActivityManager.getMemoryClass() Android G1 - 16MB Motorola Xoom - 48GB

If you need more, use android:largeHeap = "true"

Can't just ask for more memory though. Using the large heap option and getting more memory means more time spent in garbage collection.

  • Garbage collection

The GC visits all objects in the graph. Objects that it does not visit are collected.

After Gingerbread, the GC changed from Stop the World, full heap collection (>100ms pauses) to Concurrent, partial collection (<5ms pauses).

  • Tools to analyse Memory Usage

####Logs

A log of dlavik would give the following info

  • Reason for GC (GC_CONCURRENT, GC_FOR_MALLOC, GC_EXTERNAL_ALLOC(deprecated), GC_EXPLICIT (avoid))

  • The amount of memory freed

  • How much of the heap is free

  • External memory statistics

  • Pause time

A technique he suggests for detecting memory leak is to look at the size of the memory used. If it goes up steadily without going down, its possible that there is a leak.

####Heap Dump

  • Create with DDMS

Memory leaks can occur in garbage collected languages, just like it does in C. If you hold reference to a long lived object like Activity (or even its children like ViewGroup or View), it will cause a leak. For example, when a rotation takes place, the activity is collected and a new one is created. If a reference to the old one still exists, then it won't be collected.

The "retained heap" of an object is the amount of memory that would be freed if we freed the object and objects that it holds references to. A dominator tree is used to decide whether an object is a child of another.

###Android Runtime (ART)

This video is about - what it is, what improvements. x64 improvements.

####Why ART

Dalvik targeted single processor, low memory. Not designed for multiprocessing. Devices have improved by 50x compared to the G1. Improvements were made to Dalvik, such as JIT, concurrent Garbage collection.

Google wants ART to be fast, not noticed by developers, should scale, have good GC (that does not hinder devs)

Benefits

  • Devirutalize method calls

  • Faster interface invocation

  • Avoid class initialisation checks

  • Eliminiating exception checks

  • Battery, and memory improvements

Cons

  • App will startup 2-3 seconds slower the first time it is installed
  • App will occupy more space on disk since it is compiled Ahead-of-Time instead of Just-in-Time

When an APK is installed, the resources and native code are copied to the application directory. The Dex needs to be processed, for both Dalvik and ART

####Garbage collection

Change in GC. Firstly instead of a global pause for creating the object graph, all the apps are asked to supply their object graphs, so each app only pauses for creating it's own object graph.

Then it marks the objects concurrently.

Fragmentation of the heap causes large collection times (upto 50ms), so strattegies to reduce this. Iske alaawa normal standard GC optimizations like put larger objects like bitmaps into separate arrays together to avoid fragmentation. First try GC for objects allocated after last GC, kinda similar to young generation collection. These guys call it sticky collection. Split memory into two halves and move live objects into one half cleaning the other half. And lastly in-place collection.

There was some optimization associated with page management but could not understand that well.

Project Volta

Waking the device up from sleep for even a second is an expensive operation. 1 second of waking the application processor, making it fill the memory with necessary data, process it and go back to sleep sacrifices 2 minutes of standby. A single network call will make the cell radio enter standby state for the next minute or so, which consumes a lot of battery as well.

####JobScheduler API.

This is the solution to the battery issue. The API useful in such situations as:

  • The app has non-user-facing work that you can defer.
  • The app has work you'd prefer to do when the unit is plugged in.
  • The app has a task that requires network access (or requires a Wi-Fi connection).
  • The app has a number of tasks that you want to run as a batch on a regular schedule.

You can schedule the task to run under specific conditions, such as:

  • The device is charging
  • The device is connected to an unmetered network
  • The system deems the device to be idle
  • Completion with a minimum delay or within a specific deadline.

For now, this API seems to be available only in the L preview, but I personally feel that there is a good chance that it will be back-ported. If it is, we should probably use it as much as possible because other apps certainly will. This will lead to our app moving up the list in the battery consumption screen.

####Analysing battery consumption

adb shell dumpsys batterystats --charged <package-name> will give you

  • History of battery related events
  • Global statistics for the device
  • Approximated power use per UID and system component
  • Per-app mobile ms per packet
  • System UID aggregated statistics
  • App UID aggregated statistics

To generate pretty graphs, use Battery Historian(included in sdk/tools)

  1. First enable full wake lock reporting, to allow the Battery Historian tool to monitor uninterrupted over an extended period of time adb shell dumpsys batterystats --enable full-wake-history
  2. Reset battery statistics at the beginning of a measurement adb shell dumpsys batterystats --reset
  3. Generate html output historian.par [-p powerfile] bugreport.txt > out.html
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment