SlideShare a Scribd company logo
A ScyllaDB Community
Detecting Memory Leaks in Android
A/B Tests: A Production-Focused
Approach
Pavlo Stavytskyi
Google Developer Expert for Android, Kotlin
Experts
Pavlo Stavytskyi (he/him)
Google Developer Expert - Android, Kotlin
■ Software Engineer at Meta
■ Previously Software Engineer at Lyft
Memory leaks
What are memory leaks?
A memory leak occurs when objects in the app's memory that are no longer
needed are still being referenced and therefore cannot be garbage collected. This
leads to a gradual buildup of unused memory causing:
■ Performance slow down
■ Unresponsiveness
■ App crashes
Existing tools
Tools for detecting memory leaks locally:
■ LeakCanary
■ Perfetto
■ Android Studio Memory Profiler
The problem with existing tools
■ Aimed at local profiling
● Debug or profilable release builds
● Manual testing
■ Hard to predict all possible circumstances
● Permutations of feature flags
● Specific Android devices
● Other conditions
Goals of the talk
■ Discover a memory monitoring approach for Android app that allows to:
● Understand the memory footprint of the app in production
● Detect regressions in A/B tests
■ Look into a tricky P99 memory leak detected at Lyft
Metrics
Metrics
■ There is no ultimate memory usage metric.
■ Where to retrieve metrics?
● Use Linux system file structure.
● Use Android SDK.
Android Studio Memory Profiler example
PSS
Proportional set size (PSS) — the amount of private and shared memory used by
the app where the amount of shared memory is proportional to the number of
processes it is shared with.
■ If 3 processes are sharing 3MB, each process gets 1MB in PSS.
■ Used by Android Studio Memory Profiler
Full PSS breakdown
import android.os.Debug
import android.os.Debug.MemoryInfo
val memoryInfo = MemoryInfo()
Debug.getMemoryInfo(memoryInfo)
val summary: Map<String, String> = memoryInfo.getMemoryStats()
Full PSS breakdown
code: 12128 kB
stack: 496 kB
graphics: 996 kB
java-heap: 8160 kB
native-heap: 4516 kB
private-other: 2720 kB
system: 4955 kB // Includes all shared memory
total-pss: 33971 kB // A sum of everything except 'total-swap'
total-swap: 17520 kB
Just PSS
import android.os.Debug
val pssKb: Long = Debug.getPss()
Android Studio Memory Profiler example
USS
Unique set size (USS) — the amount of private memory used by the app excluding
shared memory.
■ Could be derived from PSS metrics on Android
USS
import android.os.Debug.MemoryInfo
val memoryInfo = MemoryInfo()
Debug.getMemoryInfo(memoryInfo)
val ussKb = with(memoryInfo) {
getTotalPrivateClean() + getTotalPrivateDirty()
}
Clean and dirty memory
■ Dirty memory — pages that have been modified by the app at runtime, so they
must stay committed to RAM.
■ Clean memory — unmodified copy of a file in memory, so it can be cleared if
not used.
A clean page becomes a dirty page when it no longer contains an exact copy of
the file (for example, from the result of an application operation).
What’s wrong with PSS and USS?
Calling Debug.getMemoryInfo or Debug.getPss can take hundreds of
milliseconds.
Different API for PSS
import android.os.Debug.MemoryInfo
val activityManager = context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager
val pid = intArrayOf(android.os.Process.myPid())
// Sample rate is limited to once per 5 minutes.
val memoryInfo: MemoryInfo = activityManager.getProcessMemoryInfo(pid).first()
More efficient metrics
RSS
Resident set size (RSS) — the amount of private and shared memory used by the
app where all shared memory is included.
■ If three processes are sharing 3MB, each process gets 3MB in RSS.
■ Pessimistic metric.
■ Minimal performance overhead.
How to retrieve RSS?
Refer to a system file located at /proc/[pid]/statm, where [pid] is the ID of
an application process.
■ android.os.Process.myPid() can be used to get [pid]
programmatically.
How to retrieve RSS?
Reading statm file:
■ 3693120 27503 18904 1 0 319129 0
■ (2) resident — resident set size, represented in pages.
■ rssKb = resident * 4
■ The default page size on Linux is 4 kB
USS < PSS < RSS
Evaluating the data
Reporting metrics
■ Report a snapshot on every UI screen
■ Report a snapshot with metrics periodically with a given interval
Improving A/B testing
A/B experiments allow comparing reported metrics between two app variants:
■ Treatment — the group of users that use the app with the new feature
enabled.
■ Control — the group of users that use the app in a normal state with the new
feature disabled.
Example 1 — no regression
Example 2 — regression
Additional metrics
Memory allocated in heap
JVM heap
val totalMemoryKb = Runtime.getRuntime().totalMemory() / 1024
val freeMemoryKb = Runtime.getRuntime().freeMemory() / 1024
val jvmHeapAllocatedKb = totalMemoryKb - freeMemoryKb
Native heap
import android.os.Debug
val nativeHeapAllocatedKb = Debug.getNativeHeapAllocatedSize() / 1024
Why is this approach
efficient?
Example 3 — memory leak at 99th percentile
Thank you! Let’s connect.
Pavlo Stavytskyi
pavlo.stavytskyi@gmail.com
@morfly_io
morfly.medium.com

More Related Content

PDF
Android Memory , Where is all My RAM
ODT
ACADGILD:: ANDROID LESSON-How to analyze &amp; manage memory on android like ...
PPTX
Memory management in Andoid
PDF
AndroidMemoryProfiling
PPTX
Android Memory Management
PDF
performance optimization: Memory
PDF
TechGIG_Memory leaks in_java_webnair_26th_july_2012
PPTX
Of Bytes, Cycles and Battery Life
Android Memory , Where is all My RAM
ACADGILD:: ANDROID LESSON-How to analyze &amp; manage memory on android like ...
Memory management in Andoid
AndroidMemoryProfiling
Android Memory Management
performance optimization: Memory
TechGIG_Memory leaks in_java_webnair_26th_july_2012
Of Bytes, Cycles and Battery Life

Similar to Detecting Memory Leaks in Android A/B Tests: A Production-Focused Approach by Pavlo Stavytskyi (20)

PPTX
Memory Usage in Android
PDF
Effective memory management
PDF
Effective memory management
PDF
Memory management for_android_apps
PDF
【Unite Tokyo 2018】その最適化、本当に最適ですか!? ~正しい最適化を行うためのテクニック~
PDF
How to Perform Memory Leak Test Using Valgrind
PDF
Memory Leaks in Android Applications
PDF
"Avoiding memory leaks in Android" Денис Жучинский
PPTX
Memory profiler and garbage collector in C#
PDF
Pref Presentation (2)
ODP
Memory management
PDF
Eclipse Memory Analyzer Tool
PPT
Vietnam Mobile Day 2013: Memory Management For Android Apps
PPT
[Vietnam Mobile Day 2013] - Memory management for android applications
PDF
Tuning Android for low RAM
PPTX
Android Performance Best Practices
PPTX
17-Android.pptx
PPTX
Optimizing Apps for Better Performance
PDF
Android performance tuning. Memory.
PPT
Sporar
Memory Usage in Android
Effective memory management
Effective memory management
Memory management for_android_apps
【Unite Tokyo 2018】その最適化、本当に最適ですか!? ~正しい最適化を行うためのテクニック~
How to Perform Memory Leak Test Using Valgrind
Memory Leaks in Android Applications
"Avoiding memory leaks in Android" Денис Жучинский
Memory profiler and garbage collector in C#
Pref Presentation (2)
Memory management
Eclipse Memory Analyzer Tool
Vietnam Mobile Day 2013: Memory Management For Android Apps
[Vietnam Mobile Day 2013] - Memory management for android applications
Tuning Android for low RAM
Android Performance Best Practices
17-Android.pptx
Optimizing Apps for Better Performance
Android performance tuning. Memory.
Sporar
Ad

More from ScyllaDB (20)

PDF
Understanding The True Cost of DynamoDB Webinar
PDF
Database Benchmarking for Performance Masterclass: Session 2 - Data Modeling ...
PDF
Database Benchmarking for Performance Masterclass: Session 1 - Benchmarking F...
PDF
New Ways to Reduce Database Costs with ScyllaDB
PDF
Designing Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep Dive
PDF
Powering a Billion Dreams: Scaling Meesho’s E-commerce Revolution with Scylla...
PDF
Leading a High-Stakes Database Migration
PDF
Achieving Extreme Scale with ScyllaDB: Tips & Tradeoffs
PDF
Securely Serving Millions of Boot Artifacts a Day by João Pedro Lima & Matt ...
PDF
How Agoda Scaled 50x Throughput with ScyllaDB by Worakarn Isaratham
PDF
How Yieldmo Cut Database Costs and Cloud Dependencies Fast by Todd Coleman
PDF
ScyllaDB: 10 Years and Beyond by Dor Laor
PDF
Reduce Your Cloud Spend with ScyllaDB by Tzach Livyatan
PDF
Migrating 50TB Data From a Home-Grown Database to ScyllaDB, Fast by Terence Liu
PDF
Vector Search with ScyllaDB by Szymon Wasik
PDF
Workload Prioritization: How to Balance Multiple Workloads in a Cluster by Fe...
PDF
Two Leading Approaches to Data Virtualization, and Which Scales Better? by Da...
PDF
Scaling a Beast: Lessons from 400x Growth in a High-Stakes Financial System b...
PDF
Object Storage in ScyllaDB by Ran Regev, ScyllaDB
PDF
Lessons Learned from Building a Serverless Notifications System by Srushith R...
Understanding The True Cost of DynamoDB Webinar
Database Benchmarking for Performance Masterclass: Session 2 - Data Modeling ...
Database Benchmarking for Performance Masterclass: Session 1 - Benchmarking F...
New Ways to Reduce Database Costs with ScyllaDB
Designing Low-Latency Systems with Rust and ScyllaDB: An Architectural Deep Dive
Powering a Billion Dreams: Scaling Meesho’s E-commerce Revolution with Scylla...
Leading a High-Stakes Database Migration
Achieving Extreme Scale with ScyllaDB: Tips & Tradeoffs
Securely Serving Millions of Boot Artifacts a Day by João Pedro Lima & Matt ...
How Agoda Scaled 50x Throughput with ScyllaDB by Worakarn Isaratham
How Yieldmo Cut Database Costs and Cloud Dependencies Fast by Todd Coleman
ScyllaDB: 10 Years and Beyond by Dor Laor
Reduce Your Cloud Spend with ScyllaDB by Tzach Livyatan
Migrating 50TB Data From a Home-Grown Database to ScyllaDB, Fast by Terence Liu
Vector Search with ScyllaDB by Szymon Wasik
Workload Prioritization: How to Balance Multiple Workloads in a Cluster by Fe...
Two Leading Approaches to Data Virtualization, and Which Scales Better? by Da...
Scaling a Beast: Lessons from 400x Growth in a High-Stakes Financial System b...
Object Storage in ScyllaDB by Ran Regev, ScyllaDB
Lessons Learned from Building a Serverless Notifications System by Srushith R...
Ad

Recently uploaded (20)

PPTX
international classification of diseases ICD-10 review PPT.pptx
PDF
RPKI Status Update, presented by Makito Lay at IDNOG 10
PDF
The Internet -By the Numbers, Sri Lanka Edition
PPT
isotopes_sddsadsaadasdasdasdasdsa1213.ppt
PPTX
presentation_pfe-universite-molay-seltan.pptx
PPTX
Introuction about ICD -10 and ICD-11 PPT.pptx
DOCX
Unit-3 cyber security network security of internet system
PDF
Best Practices for Testing and Debugging Shopify Third-Party API Integrations...
PDF
Testing WebRTC applications at scale.pdf
PPT
tcp ip networks nd ip layering assotred slides
PPTX
522797556-Unit-2-Temperature-measurement-1-1.pptx
PPTX
E -tech empowerment technologies PowerPoint
PDF
An introduction to the IFRS (ISSB) Stndards.pdf
PDF
WebRTC in SignalWire - troubleshooting media negotiation
PPTX
Introuction about WHO-FIC in ICD-10.pptx
PDF
Decoding a Decade: 10 Years of Applied CTI Discipline
PPTX
Slides PPTX World Game (s) Eco Economic Epochs.pptx
PPTX
Funds Management Learning Material for Beg
PPTX
Job_Card_System_Styled_lorem_ipsum_.pptx
PPTX
innovation process that make everything different.pptx
international classification of diseases ICD-10 review PPT.pptx
RPKI Status Update, presented by Makito Lay at IDNOG 10
The Internet -By the Numbers, Sri Lanka Edition
isotopes_sddsadsaadasdasdasdasdsa1213.ppt
presentation_pfe-universite-molay-seltan.pptx
Introuction about ICD -10 and ICD-11 PPT.pptx
Unit-3 cyber security network security of internet system
Best Practices for Testing and Debugging Shopify Third-Party API Integrations...
Testing WebRTC applications at scale.pdf
tcp ip networks nd ip layering assotred slides
522797556-Unit-2-Temperature-measurement-1-1.pptx
E -tech empowerment technologies PowerPoint
An introduction to the IFRS (ISSB) Stndards.pdf
WebRTC in SignalWire - troubleshooting media negotiation
Introuction about WHO-FIC in ICD-10.pptx
Decoding a Decade: 10 Years of Applied CTI Discipline
Slides PPTX World Game (s) Eco Economic Epochs.pptx
Funds Management Learning Material for Beg
Job_Card_System_Styled_lorem_ipsum_.pptx
innovation process that make everything different.pptx

Detecting Memory Leaks in Android A/B Tests: A Production-Focused Approach by Pavlo Stavytskyi

  • 1. A ScyllaDB Community Detecting Memory Leaks in Android A/B Tests: A Production-Focused Approach Pavlo Stavytskyi Google Developer Expert for Android, Kotlin Experts
  • 2. Pavlo Stavytskyi (he/him) Google Developer Expert - Android, Kotlin ■ Software Engineer at Meta ■ Previously Software Engineer at Lyft
  • 4. What are memory leaks? A memory leak occurs when objects in the app's memory that are no longer needed are still being referenced and therefore cannot be garbage collected. This leads to a gradual buildup of unused memory causing: ■ Performance slow down ■ Unresponsiveness ■ App crashes
  • 5. Existing tools Tools for detecting memory leaks locally: ■ LeakCanary ■ Perfetto ■ Android Studio Memory Profiler
  • 6. The problem with existing tools ■ Aimed at local profiling ● Debug or profilable release builds ● Manual testing ■ Hard to predict all possible circumstances ● Permutations of feature flags ● Specific Android devices ● Other conditions
  • 7. Goals of the talk ■ Discover a memory monitoring approach for Android app that allows to: ● Understand the memory footprint of the app in production ● Detect regressions in A/B tests ■ Look into a tricky P99 memory leak detected at Lyft
  • 9. Metrics ■ There is no ultimate memory usage metric. ■ Where to retrieve metrics? ● Use Linux system file structure. ● Use Android SDK.
  • 10. Android Studio Memory Profiler example
  • 11. PSS Proportional set size (PSS) — the amount of private and shared memory used by the app where the amount of shared memory is proportional to the number of processes it is shared with. ■ If 3 processes are sharing 3MB, each process gets 1MB in PSS. ■ Used by Android Studio Memory Profiler
  • 12. Full PSS breakdown import android.os.Debug import android.os.Debug.MemoryInfo val memoryInfo = MemoryInfo() Debug.getMemoryInfo(memoryInfo) val summary: Map<String, String> = memoryInfo.getMemoryStats()
  • 13. Full PSS breakdown code: 12128 kB stack: 496 kB graphics: 996 kB java-heap: 8160 kB native-heap: 4516 kB private-other: 2720 kB system: 4955 kB // Includes all shared memory total-pss: 33971 kB // A sum of everything except 'total-swap' total-swap: 17520 kB
  • 14. Just PSS import android.os.Debug val pssKb: Long = Debug.getPss()
  • 15. Android Studio Memory Profiler example
  • 16. USS Unique set size (USS) — the amount of private memory used by the app excluding shared memory. ■ Could be derived from PSS metrics on Android
  • 17. USS import android.os.Debug.MemoryInfo val memoryInfo = MemoryInfo() Debug.getMemoryInfo(memoryInfo) val ussKb = with(memoryInfo) { getTotalPrivateClean() + getTotalPrivateDirty() }
  • 18. Clean and dirty memory ■ Dirty memory — pages that have been modified by the app at runtime, so they must stay committed to RAM. ■ Clean memory — unmodified copy of a file in memory, so it can be cleared if not used. A clean page becomes a dirty page when it no longer contains an exact copy of the file (for example, from the result of an application operation).
  • 19. What’s wrong with PSS and USS? Calling Debug.getMemoryInfo or Debug.getPss can take hundreds of milliseconds.
  • 20. Different API for PSS import android.os.Debug.MemoryInfo val activityManager = context.getSystemService(Context.ACTIVITY_SERVICE) as ActivityManager val pid = intArrayOf(android.os.Process.myPid()) // Sample rate is limited to once per 5 minutes. val memoryInfo: MemoryInfo = activityManager.getProcessMemoryInfo(pid).first()
  • 22. RSS Resident set size (RSS) — the amount of private and shared memory used by the app where all shared memory is included. ■ If three processes are sharing 3MB, each process gets 3MB in RSS. ■ Pessimistic metric. ■ Minimal performance overhead.
  • 23. How to retrieve RSS? Refer to a system file located at /proc/[pid]/statm, where [pid] is the ID of an application process. ■ android.os.Process.myPid() can be used to get [pid] programmatically.
  • 24. How to retrieve RSS? Reading statm file: ■ 3693120 27503 18904 1 0 319129 0 ■ (2) resident — resident set size, represented in pages. ■ rssKb = resident * 4 ■ The default page size on Linux is 4 kB
  • 25. USS < PSS < RSS
  • 27. Reporting metrics ■ Report a snapshot on every UI screen ■ Report a snapshot with metrics periodically with a given interval
  • 28. Improving A/B testing A/B experiments allow comparing reported metrics between two app variants: ■ Treatment — the group of users that use the app with the new feature enabled. ■ Control — the group of users that use the app in a normal state with the new feature disabled.
  • 29. Example 1 — no regression
  • 30. Example 2 — regression
  • 33. JVM heap val totalMemoryKb = Runtime.getRuntime().totalMemory() / 1024 val freeMemoryKb = Runtime.getRuntime().freeMemory() / 1024 val jvmHeapAllocatedKb = totalMemoryKb - freeMemoryKb
  • 34. Native heap import android.os.Debug val nativeHeapAllocatedKb = Debug.getNativeHeapAllocatedSize() / 1024
  • 35. Why is this approach efficient?
  • 36. Example 3 — memory leak at 99th percentile
  • 37. Thank you! Let’s connect. Pavlo Stavytskyi pavlo.stavytskyi@gmail.com @morfly_io morfly.medium.com