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

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

PDF
Tuning Android for low RAM
Chris Simmonds
 
PPTX
Raising ux bar with offline first design
Kyrylo Reznykov
 
PDF
Effective memory management
Yurii Kotov
 
PDF
Effective memory management
Denis Zhuchinski
 
PDF
Android Platform Debugging and Development
Karim Yaghmour
 
PDF
Android Platform Debugging and Development
Opersys inc.
 
PPTX
Optimisation and performance in Android
Rakesh Jha
 
PPTX
CS345 16 - Ch07 Memory management 1.pptx
rahulborate13
 
ODT
ACADGILD:: ANDROID LESSON-How to analyze &amp; manage memory on android like ...
Padma shree. T
 
PDF
WebSphere Technical University: Introduction to the Java Diagnostic Tools
Chris Bailey
 
PPT
Large Scale Log collection using LogStash & mongoDB
Gaurav Bhardwaj
 
PDF
Working with the AOSP - Linaro Connect Asia 2013
Opersys inc.
 
PDF
The Green Lab - [04 B] [PWA] Experiment setup
Ivano Malavolta
 
PDF
Android Platform Debugging and Development
Opersys inc.
 
PDF
Android Platform Debugging and Development
Opersys inc.
 
ODP
From Java Code to Java Heap: Understanding the Memory Usage of Your App - Ch...
jaxLondonConference
 
ODP
Q4.11: Porting Android to new Platforms
Linaro
 
PDF
Android Platform Debugging and Development
Opersys inc.
 
PDF
Android on Intel Architecture: ROM Cooking Tutorial
Ron Munitz
 
PDF
IBM Monitoring and Diagnostic Tools - GCMV 2.8
Chris Bailey
 
Tuning Android for low RAM
Chris Simmonds
 
Raising ux bar with offline first design
Kyrylo Reznykov
 
Effective memory management
Yurii Kotov
 
Effective memory management
Denis Zhuchinski
 
Android Platform Debugging and Development
Karim Yaghmour
 
Android Platform Debugging and Development
Opersys inc.
 
Optimisation and performance in Android
Rakesh Jha
 
CS345 16 - Ch07 Memory management 1.pptx
rahulborate13
 
ACADGILD:: ANDROID LESSON-How to analyze &amp; manage memory on android like ...
Padma shree. T
 
WebSphere Technical University: Introduction to the Java Diagnostic Tools
Chris Bailey
 
Large Scale Log collection using LogStash & mongoDB
Gaurav Bhardwaj
 
Working with the AOSP - Linaro Connect Asia 2013
Opersys inc.
 
The Green Lab - [04 B] [PWA] Experiment setup
Ivano Malavolta
 
Android Platform Debugging and Development
Opersys inc.
 
Android Platform Debugging and Development
Opersys inc.
 
From Java Code to Java Heap: Understanding the Memory Usage of Your App - Ch...
jaxLondonConference
 
Q4.11: Porting Android to new Platforms
Linaro
 
Android Platform Debugging and Development
Opersys inc.
 
Android on Intel Architecture: ROM Cooking Tutorial
Ron Munitz
 
IBM Monitoring and Diagnostic Tools - GCMV 2.8
Chris Bailey
 

More from ScyllaDB (20)

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

Recently uploaded (20)

PPT
Computer Securityyyyyyyy - Chapter 1.ppt
SolomonSB
 
PPTX
本科硕士学历佛罗里达大学毕业证(UF毕业证书)24小时在线办理
Taqyea
 
PPTX
ONLINE BIRTH CERTIFICATE APPLICATION SYSYTEM PPT.pptx
ShyamasreeDutta
 
PPTX
Research Design - Report on seminar in thesis writing. PPTX
arvielobos1
 
PPTX
PE introd.pptxfrgfgfdgfdgfgrtretrt44t444
nepmithibai2024
 
PPTX
英国假毕业证诺森比亚大学成绩单GPA修改UNN学生卡网上可查学历成绩单
Taqyea
 
PDF
Build Fast, Scale Faster: Milvus vs. Zilliz Cloud for Production-Ready AI
Zilliz
 
PPTX
西班牙武康大学毕业证书{UCAMOfferUCAM成绩单水印}原版制作
Taqyea
 
PPT
introductio to computers by arthur janry
RamananMuthukrishnan
 
PPTX
INTEGRATION OF ICT IN LEARNING AND INCORPORATIING TECHNOLOGY
kvshardwork1235
 
PPTX
unit 2_2 copy right fdrgfdgfai and sm.pptx
nepmithibai2024
 
PPTX
原版西班牙莱昂大学毕业证(León毕业证书)如何办理
Taqyea
 
PDF
DevOps Design for different deployment options
henrymails
 
PDF
Web Hosting for Shopify WooCommerce etc.
Harry_Phoneix Harry_Phoneix
 
PPTX
Lec15_Mutability Immutability-converted.pptx
khanjahanzaib1
 
PPTX
L1A Season 1 Guide made by A hegy Eng Grammar fixed
toszolder91
 
PPTX
L1A Season 1 ENGLISH made by A hegy fixed
toszolder91
 
PPTX
一比一原版(SUNY-Albany毕业证)纽约州立大学奥尔巴尼分校毕业证如何办理
Taqyea
 
PDF
𝐁𝐔𝐊𝐓𝐈 𝐊𝐄𝐌𝐄𝐍𝐀𝐍𝐆𝐀𝐍 𝐊𝐈𝐏𝐄𝐑𝟒𝐃 𝐇𝐀𝐑𝐈 𝐈𝐍𝐈 𝟐𝟎𝟐𝟓
hokimamad0
 
PPT
Agilent Optoelectronic Solutions for Mobile Application
andreashenniger2
 
Computer Securityyyyyyyy - Chapter 1.ppt
SolomonSB
 
本科硕士学历佛罗里达大学毕业证(UF毕业证书)24小时在线办理
Taqyea
 
ONLINE BIRTH CERTIFICATE APPLICATION SYSYTEM PPT.pptx
ShyamasreeDutta
 
Research Design - Report on seminar in thesis writing. PPTX
arvielobos1
 
PE introd.pptxfrgfgfdgfdgfgrtretrt44t444
nepmithibai2024
 
英国假毕业证诺森比亚大学成绩单GPA修改UNN学生卡网上可查学历成绩单
Taqyea
 
Build Fast, Scale Faster: Milvus vs. Zilliz Cloud for Production-Ready AI
Zilliz
 
西班牙武康大学毕业证书{UCAMOfferUCAM成绩单水印}原版制作
Taqyea
 
introductio to computers by arthur janry
RamananMuthukrishnan
 
INTEGRATION OF ICT IN LEARNING AND INCORPORATIING TECHNOLOGY
kvshardwork1235
 
unit 2_2 copy right fdrgfdgfai and sm.pptx
nepmithibai2024
 
原版西班牙莱昂大学毕业证(León毕业证书)如何办理
Taqyea
 
DevOps Design for different deployment options
henrymails
 
Web Hosting for Shopify WooCommerce etc.
Harry_Phoneix Harry_Phoneix
 
Lec15_Mutability Immutability-converted.pptx
khanjahanzaib1
 
L1A Season 1 Guide made by A hegy Eng Grammar fixed
toszolder91
 
L1A Season 1 ENGLISH made by A hegy fixed
toszolder91
 
一比一原版(SUNY-Albany毕业证)纽约州立大学奥尔巴尼分校毕业证如何办理
Taqyea
 
𝐁𝐔𝐊𝐓𝐈 𝐊𝐄𝐌𝐄𝐍𝐀𝐍𝐆𝐀𝐍 𝐊𝐈𝐏𝐄𝐑𝟒𝐃 𝐇𝐀𝐑𝐈 𝐈𝐍𝐈 𝟐𝟎𝟐𝟓
hokimamad0
 
Agilent Optoelectronic Solutions for Mobile Application
andreashenniger2
 
Ad

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 [email protected] @morfly_io morfly.medium.com