Android Performance

Android Performance

Focus on Android Performance

loading
RenderThread Workflow in Android hwui

Preface

This article serves as a set of learning notes documenting the basic workflow of RenderThread in hwui as introduced in Android 5.0. Since these are notes, some details might not be exhaustive. Instead, I aim to walk through the general flow and highlight the key stages of its operation for future reference when debugging.

The image below shows a Systrace capture of the first Draw operation by the RenderThread during an application startup. We can trace the RenderThread workflow by observing the sequence of events in this trace. If you are familiar with the application startup process, you know that the entire interface is only displayed on the phone after the first drawFrame is completed. Before this, the user sees the application’s StartingWindow.

Java 7 HashMap Source Code Analysis

Linked lists and arrays allow elements to be arranged in an order of our choice. However, if you want to find a specific element but have forgotten its position, you must visit every element until you find it. This can consume significant time if the collection is large. A data structure that allows for rapidly finding objects is the hash table.

HashMap is an implementation of the Map interface based on a hash table. This implementation provides all optional mapping operations and permits null values and null keys. (The HashMap class is roughly equivalent to Hashtable, except that it is unsynchronized and permits nulls.) This class makes no guarantees as to the order of the map; in particular, it does not guarantee that the order will remain constant over time.

Android Code Memory Optimization Suggestions - OnTrimMemory

Android Memory Optimization Series:

  1. Android Code Memory Optimization Suggestions - Android (Official)
  2. Android Code Memory Optimization Suggestions - Java (Official)
  3. Android Code Memory Optimization Suggestions - Android Resources
  4. Android Code Memory Optimization Suggestions - OnTrimMemory

The onTrimMemory callback is an API introduced in Android 4.0. It provides hints to developers when system memory is low, allowing them to release resources proactively to avoid being killed by the OS. This ensures the app stays in the background longer and starts faster when the user returns.

This article uses a Q&A format to explain the usage and effectiveness of the onTrimMemory callback across various scenarios. If you want to build high-performance Android apps with great user experiences, don’t miss this.

Android Code Memory Optimization Suggestions - Android Resources

Android Memory Optimization Series:

  1. Android Code Memory Optimization Suggestions - Android (Official)
  2. Android Code Memory Optimization Suggestions - Java (Official)
  3. Android Code Memory Optimization Suggestions - Android Resources
  4. Android Code Memory Optimization Suggestions - OnTrimMemory

This article focuses on common memory leak scenarios in Android application development. Having a baseline understanding of memory management before writing code leads to much more robust applications. This post starts with resource usage in Android and covers optimizations for Bitmaps, database queries, Nine-Patch assets, overdraw, and more.

Android Code Memory Optimization Suggestions - Android (Official)

Android Memory Optimization Series:

  1. Android Code Memory Optimization Suggestions - Android (Official)
  2. Android Code Memory Optimization Suggestions - Java (Official)
  3. Android Code Memory Optimization Suggestions - Android Resources
  4. Android Code Memory Optimization Suggestions - OnTrimMemory

To ensure the Garbage Collector (GC) can properly release memory, it’s crucial to avoid memory leaks (often caused by global or static member variables holding object references) and to release references when they are no longer needed. For most apps, the GC handles the rest: if an object is no longer reachable, its memory is reclaimed.

High-performance software requires proactive memory management throughout the development lifecycle. Android provides several specific guidelines and techniques to help developers achieve excellent memory performance.

Android Code Memory Optimization Suggestions - Java (Official)

Android Memory Optimization Series:

  1. Android Code Memory Optimization Suggestions - Android (Official)
  2. Android Code Memory Optimization Suggestions - Java (Official)
  3. Android Code Memory Optimization Suggestions - Android Resources
  4. Android Code Memory Optimization Suggestions - OnTrimMemory

This article introduces micro-optimization techniques that, when combined, contribute to the overall performance of an app, although they don’t provide massive gains compared to choosing the right algorithms and data structures. You should incorporate these tips into your coding habits to improve efficiency.

This content is based on the Google Official Training for Performance Optimization, specifically focusing on high-performance Android code. I recommend all Android developers read these guidelines and apply these principles in their work.

A Detailed Guide to Java Singleton Pattern

The Singleton pattern, also known as the single-instance pattern, is a widely used software design pattern. When apply this pattern, the class must ensure that only one instance of the singleton object exists. In this article, we will explore the two primary ways to construct a singleton pattern and finally introduce a sophisticated yet concise approach.

Android Performance Patterns: Profile GPU Rendering

Series Catalog:

  1. Overview of Android Performance Patterns
  2. Android Performance Patterns: Render Performance
  3. Android Performance Patterns: Understanding Overdraw
  4. Android Performance Patterns: Understanding VSYNC
  5. Android Performance Patterns: Profile GPU Rendering

“If you can measure it, you can optimize it” is a common term in the computing world, and for Android’s rendering system, the same thing holds true. In order to optimize your pipeline to be more efficient for rendering, you need a tool to give you feedback on where the current perf problems lie.

In this video, Colt McAnlis walks you through an on-device tool built for this exact reason. “Profile GPU Rendering” will help you understand the stages of the rendering pipeline, see which portions might be taking too long, and decide what to do about it in your application.

Profile GPU Rendering Tool

Rendering performance issues are often the culprits stealing your precious frames. These problems are easy to create but also easy to track with the right tools. Using the Profile GPU Rendering tool, you can see right on your device exactly what is causing your application to stutter or slow down.

Android Performance Patterns: Understanding VSYNC

Series Catalog:

  1. Overview of Android Performance Patterns
  2. Android Performance Patterns: Render Performance
  3. Android Performance Patterns: Understanding Overdraw
  4. Android Performance Patterns: Understanding VSYNC
  5. Android Performance Patterns: Profile GPU Rendering

Unbeknownst to most developers, there’s a simple hardware design that defines everything about how fast your application can draw things to the screen.

You may have heard the term VSYNC - VSYNC stands for vertical synchronization and it’s an event that happens every time your screen starts to refresh the content it wants to show you.

Effectively, VSYNC is the product of two components: Refresh Rate (how fast the hardware can refresh the screen), and Frames Per Second (how fast the GPU can draw images). In this video, Colt McAnlis walks through each of these topics and discusses where VSYNC (and the 16ms rendering barrier) comes from, and why it’s critical to understand if you want a silky smooth application.

Basic Concepts

To develop a high-performance application, you first need to understand how the hardware works. The perceived speed of an app is often misunderstood as a raw hardware processing problem, but the real root is often rendering performance. To improve rendering, you must understand VSYNC.

Android Performance Patterns: Understanding Overdraw

Series Catalog:

  1. Overview of Android Performance Patterns
  2. Android Performance Patterns: Render Performance
  3. Android Performance Patterns: Understanding Overdraw
  4. Android Performance Patterns: Understanding VSYNC
  5. Android Performance Patterns: Profile GPU Rendering

One of the most problematic performance problems on Android is the easiest to create; thankfully, it’s also easy to fix.

OVERDRAW is a term used to describe how many times a pixel has been re-drawn in a single frame of rendering. It’s a troublesome issue, because in most cases, pixels that are overdrawn do not end up contributing to the final rendered image. As such, it amounts to wasted work for your GPU and CPU.

Fixing overdraw has everything to do with using the available on-device tools, like Show GPU Overdraw, and then adjusting your view hierarchy in order to reduce areas where it may be occurring.

What is Overdraw?

At the beginning of the video, the author uses a house painter as an analogy: painting a wall is hard work, and if you have to repaint it because you don’t like the color, the first layer was a waste of effort. Similarly, in your application, any work that doesn’t end up on the final screen is wasted. When you try to balance high performance with perfect design, you often run into a common performance issue: Overdraw!

Overdraw represents a situation where a single pixel on the screen is painted more than once within a single frame. As shown in the image below, imagine a stack of overlapping cards. The active card is on top, while the inactive ones are buried beneath. This means the effort spent rendering those buried cards is wasted because they are invisible to the user. We are wasting GPU time rendering things that don’t contribute to the final image.

Android Performance Patterns: Render Performance

Series Catalog:

  1. Overview of Android Performance Patterns
  2. Android Performance Patterns: Render Performance
  3. Android Performance Patterns: Understanding Overdraw
  4. Android Performance Patterns: Understanding VSYNC
  5. Android Performance Patterns: Profile GPU Rendering

Rendering performance is all about how fast you can draw your activity, and get it updated on the screen. Success here means your users feeling like your application is smooth and responsive, which means that you’ve got to get all your logic completed, and all your rendering done in 16ms or less, each and every frame. But that might be a bit more difficult than you think.

In this video, Colt McAnlis takes a look at what “rendering performance” means to developers, alongside some of the most common pitfalls that are ran into; and let’s not forget the important stuff: the tools that help you track down, and fix these issues before they become large problems.

Android Rendering Knowledge

When you think you’ve developed a world-changing app, your users might not agree. They might think your app is slow and laggy, failing to achieve the smoothness they expect, let alone changing the world. Recycle bin, here it comes! Wait! My app is perfectly smooth on my Nexus 5? How can you say it’s slow? If you know anything about Android fragmentation, you’d know that many low-end phones don’t have the powerful processor and GPU of a Nexus 5, nor do they have an unpolluted stock system.

If a large number of users complain that your app is laggy, don’t just blame their hardware. Sometimes the problem lies within the app itself, meaning your Android app has serious rendering performance issues. Only by understanding the root cause can you solve the problem effectively. Thus, knowing how Android rendering works is essential for any Android developer.

Overview of Android Performance Patterns

Series Catalog:

  1. Overview of Android Performance Patterns
  2. Android Performance Patterns: Render Performance
  3. Android Performance Patterns: Understanding Overdraw
  4. Android Performance Patterns: Understanding VSYNC
  5. Android Performance Patterns: Profile GPU Rendering

On January 6, 2015, Google officially released a series of short videos about Android performance optimization titled Android Performance Patterns. This series is available on YouTube.

Android Performance Patterns Overview

Official Introduction:

Android Performance Patterns is a collection of videos focused entirely on helping developers write faster, more performant Android Applications. On one side, it’s about peeling back the layers of the Android System, and exposing how things are working under the hood. On the other side, it’s about teaching you how the tools work, and what to look for in order to extract the right perf out of your app.

But at the end of the day, Android Performance Patterns is all about giving you the right resources at the right time to help make the fastest, smoothest, most awesome experience for your users. And that’s the whole point, right?

In short, it’s a series of videos explaining Android performance. These videos are very short, typically between 3 to 5 minutes. The speakers talk very fast, which was quite a challenge for non-native listeners before subtitles were available. The good news is that these videos now have full subtitles.

While the videos are short, they are packed with information. A single sentence mentioned by the speaker might require hours of research to understand the underlying principle or how to use a specific debugging tool. This means the series doesn’t directly teach you “how to optimize your app” step-by-step; rather, it tells you what you need to know about Android performance so that you know which tools to use, what steps to take, and what goals to aim for.

Android Memory Optimization (3) - Viewing Original Bitmaps in MAT

This is the final article in our MAT series, detailing how to reconstruct original images from memory snapshots to debug leaks.

  1. Android Memory Optimization (1) - Introduction to MAT
  2. Android Memory Optimization (2) - Advanced MAT Usage
  3. Android Memory Optimization (3) - Viewing Original Bitmaps in MAT

When using MAT to analyze Android memory, you’ll frequently encounter Bitmap and BitmapDrawable$BitmapState objects. In many cases, these Bitmaps consume the majority of the heap. Memory leaks caused by Bitmaps are especially critical and must be handled promptly. When a potential image-related leak is found, seeing the actual image contents can be invaluable for diagnosis.

This article explains how to restore a Bitmap array object in MAT back into a viewable image.

Android Memory Optimization (2) - Advanced MAT Usage

This is the second article in our MAT series, focusing on advanced techniques for analyzing memory issues in Java and Android applications.

  1. Android Memory Optimization (1) - Introduction to MAT
  2. Android Memory Optimization (2) - Advanced MAT Usage
  3. Android Memory Optimization (3) - Viewing Original Bitmaps in MAT

Characteristics of Java Memory Leaks

  • Main features: Reachable but Useless.
  • Useless: Objects created but not released after they are no longer needed.
  • Inefficient: Re-creating new objects for tasks where existing ones could be reused.

Advanced MAT Techniques

Dumping Memory with Android Studio

Modern versions of Android Studio make capturing heap dumps easy:
Android Studio Memory Profiler