Improve Your App’s Performance With Android Profilers
An overview of Android Studio Profilers
In my previous post, we saw how to optimize UI performance but UI is not the only reason for apps with bad performance.
There may be a lot of reasons like bad CPU usage, unnecessary memory consumption, poor implementation of battery resources, etc. To debug and overcome these issues, in Android Studio 3.0 there is a section called Profiler.
In this post, we will have an overview of Profilers.
A Profiler is a suite of tools to explore, optimize, and troubleshoot performance. The Android Profiler section in Android Studio 3.0 and higher replaces the Android Monitor tools.
Android Profiler tools provide real-time data to help us to understand how our app uses CPU, memory, network, and battery resources. Let’s check the Profilers available in Android Studio.
- Network Profiler
- Energy Profiler
- Memory Profiler
- CPU Profiler
To open the Profiler window, choose View > Tool Windows > Profiler or click Profile, or the below icon in the toolbar.
To inspect the app, we need to build and deploy the app. Android Profiler continues to collect profiling data until you disconnect the device or click End Session.
The main view of the Profiler shows us the usage stats of CPU, network, memory, and energy in real-time. Clicking on any of the charts takes us into a detailed view of each section.
Let’s have an overview of what the Profiler section looks like and what it consists of.
- Android Profiler shows the process and device currently being profiled.
- In the Sessions pane, choose which session to view or start a new profiling session.
- Use the zoom buttons to control how much of the timeline to view, or use the Attach to live button to jump to real-time updates.
- The event timeline shows events related to user input, including keyboard activity, volume control changes, and screen rotations.
- The shared timeline view, which includes graphs for CPU, memory, network, and energy usage.
The Network Profiler gives a high-level overview of the networking state of the selected app. The Network Profiler displays real-time network activity on a timeline, showing data sent and received, as well as the current number of connections.
This lets you examine how and when your app transfers data, and optimize the underlying code appropriately. There is also a thread view where we can see where the work is being performed.
The graph shows the actual network activity including bytes sent and received. The graph keeps on moving if network requests are happening.
In the top-right corner, you can find the zoom and pause button to inspect a particular piece of code. After selecting a portion of the ph, it gives you the following view:
It lists all the connection requests with their timelines in that selected portion including the data size, time taken, etc.
If you want to inspect the data of a request, click on the event in the connection view and then, on the right-hand side, a widow with the details of the request gets displayed as below.
It displays actual network call request response data with the call stack, payloads, etc.
Without any interceptor, you can now see the entire request, response body, and other details of the request. It also displays the images if available and has syntax formation for XML and JSON.
Energy Profiler helps us to find the problems that could cause energy-related issues. It visualizes the breakdown of apps’ estimated energy usage of system components.
The Energy Profiler monitors the use of the CPU, network radio, and GPS sensor, and it displays a visualization of how much energy each of these components uses.
We can inspect background events that may cause a battery drain. We can use the Energy Profiler to find system events that can affect energy consumption, including wake locks, jobs, and alarms, etc.
The energy profiler looks like below:
Open the System Event pane and show details for events, such as jobs or network calls or wake locks and select a range in the Energy timeline.
This gives the details of the event. For example, in the above pic, we inspected a job that displayed the job details in the right-hand side panel with the call stack.
The Memory Profiler is a component that helps us to identify memory leaks and memory churn that can lead to stutter, freezes, and even app crashes.
It shows a real-time graph of your app’s memory use and lets you capture a heap dump, force garbage collections, and track memory allocations.
While developing our apps, we sometimes encounter memory leaks due to many reasons.
One of the most important reasons is unused objects not being garbage collected. Even though the Android system takes care of these memory allocations and garbage collections, at some point there may be a chance we might allocate more memory to some objects.
This may happen even before the garbage collector cleans off the previous objects which may cause freezing of an app, skip frames, or crash, etc.
Sometimes, we may even consume memory while the app is in the background state which, in turn, results in restart of the app by the system without resuming it.
To prevent these problems, we should use the Memory Profiler to do the following:
- Look for undesirable memory allocation patterns in the timeline that might be causing performance problems.
- Dump the Java heap to see which objects are using up memory at any given time. Several heap dumps over an extended period can help identify memory leaks.
- Record memory allocations during normal and extreme user interaction to identify exactly where your code is either allocating too many objects in a short time or allocating objects that become leaked.
- A button to force a garbage collection event.
- A button to capture a heap dump.
- Note: A button to record memory allocations appears to the right of the heap dump button only when connected to a device running Android 7.1 (API level 25) or lower.
- Buttons to zoom in/out of the timeline.
- A dropdown menu to specify how frequently the profiler captures memory allocations. Selecting the appropriate option may help you improve app performance while profiling.
- Buttons to zoom in/out of the timeline.
- A button to jump forward to the live memory data.
- The event timeline, which shows the activity states, user input events, and screen rotation events.
- The memory use timeline, which includes the following:
- A stacked graph of how much memory is being used by each memory category, as indicated by the y-axis on the left and the color key at the top.
- A dashed line indicates the number of allocated objects, as indicated by the y-axis on the right.
- An icon for each garbage collection event.
As this is going to be too long, I will be writing in detail on garbage collection, heap dump, and the memory allocation tracker in my upcoming post. If you are eager to know more, please check out the links below, in the references section.
Optimizing our app’s CPU usage has many advantages, such as providing a faster and smoother user experience and preserving device battery life.
You can use the CPU Profiler to inspect your app’s CPU usage and thread activity in real-time while interacting with your app, or you can inspect the CPU Profiler’s Android details in recorded method traces, function traces, and system traces.
Click on the record button by choosing one option from the drop-down. Interact with the app for some time and then hit the stop button.
The CPU Profiler automatically selects the recorded time range and displays its tracing information in the trace pane. After recording the activity, we can export the traces for later inspection. We can import the traces by hitting
+ in the left-top menu.
We can inspect how long it takes for an app to render each frame on the main thread and
RenderThread to investigate bottlenecks that cause UI jank and low frame rates.
To see frame rendering data, record a trace using a configuration that allows you to trace system calls. After recording the trace, look for info about each frame under the section called FRAMES.
That’s all, for now, we will deep-dive into Memory and CPU Profilers in upcoming posts.
Please let me know your suggestions and comments.
Thank you for reading.