Analysis of Android Virtual Memory and Address Space in QQ Music/Karaoke App
The article explains Android virtual memory concepts, address space limits for 32‑ and 64‑bit apps, layout of QQ Music/Karaoke process memory, tools for inspecting /proc/pid/smaps, and shows how memory growth (e.g., loading libYTCommon.so) can cause 32‑bit apps to hit the 4 GB limit and crash.
"Karaoke Memory Part 1 – Online Monitoring and Comprehensive Governance" "Karaoke Memory Part 2 – Virtual Memory Overview" "Karaoke Memory Part 3 – Native Memory Analysis and Monitoring"
1. Introduction
In a multitasking operating system, each process has an independent virtual address space. Using virtual addresses for memory access brings several advantages:
Processes can use a contiguous address space to access non‑contiguous physical memory, simplifying memory management.
Isolation between processes and physical memory protects each process's data.
Programs can address a space far larger than the available physical memory; virtual pages do not occupy physical RAM until they are accessed, facilitating swapping between memory and disk.
Android has gone through several allocators such as dlmalloc , jemalloc , scudo . The actual allocation and release are performed via brk / sbrk (changing the data segment size) or mmap / munmap for anonymous mappings. Calls to malloc return virtual addresses; physical memory is only allocated on a page‑fault.
Paging divides memory into small, contiguous blocks called pages (usually 4 KB). For virtual memory, pages can be in the following states:
Not Present:页面分配后未映射到物理内存;又或是作为干净页即将被内核清除
Resident:当页面映射到物理内存后,需常驻于内存中,根据其内容是否存在文件备份,可划分为两种类型:
Clean(干净页):仅适用于文件映射,加载到内存后不曾被更改,当内存不足时可由内核进行清除
Dirty(脏页):匿名映射(不存在文件备份)或页面内容与磁盘不同。这种情况下无法由内核进行清除,因为会导致数据丢失,但可由Swapped机制进行交换处理
Swapped:脏页可被交换到磁盘上,当再次发生缺页中断时才被重新加载到内存;在Android中表示通过ZRAM进行了压缩,但仍会占用部分内存2. Address Space Size
2.1 32‑bit address space
ARM 32‑bit CPUs can address 2^32 = 4 GB , with part reserved for the kernel. Linux provides three split parameters: VMSPLIT_3G , VMSPLIT_2G , VMSPLIT_1G . The default is VMSPLIT_3G , giving user space 3 GB and kernel space 1 GB.
2.2 64‑bit address space
ARM 64‑bit CPUs theoretically support 2^64 addresses, but only a subset is usable. The architecture defines a 48‑bit virtual address space (256 TB) for most implementations; 52‑bit support is optional. Page sizes of 4 KB, 16 KB, and 64 KB are available. Using 64 KB pages allows 52‑bit addressing; otherwise, only 48‑bit is usable.
Android defaults to 4 KB pages ( CONFIG_ARM64_4K_PAGES ) and a 39‑bit virtual address space ( CONFIG_ARM64_VA_BITS=39 ) managed by a 3‑level page table ( CONFIG_PGTABLE_LEVELS=3 ). Consequently, a 64‑bit Android app can address up to 2^39 = 512 GB .
2.3 32‑bit apps on 64‑bit architecture
When a 32‑bit app runs on a 64‑bit system, it can exclusively use the low 4 GB of virtual address space, while the kernel retains the high 512 GB.
--------------------> +--------------------------+
ffff:ffff:ffff:ffff | |
| Kernel (512G) |
ffff:ff80:0000:0000 | |
--------------------> +--------------------------+
ffff:ff7f:ffff:ffff |//////////////////////////|
|//////////////////////////|
|//////////////////////////|
z //////////////////////// z
|//////////////////////////|
|//////////////////////////|
0000:0001:0000:0000 |//////////////////////////|
--------------------> +--------------------------+
0000:0000:ffff:ffff | |
| User (4G) |
0000:0000:0000:0000 | |
--------------------> +--------------------------+Thus, 32‑bit apps are limited to 4 GB virtual address space, while 64‑bit apps can use up to 512 GB.
2.4 Limitations of memory allocation
The number of virtual memory areas is limited (default /proc/sys/vm/max_map_count = 65536 ). Android manages physical memory via LowMemoryKiller and ZRAM . When a 32‑bit app exhausts its virtual address space, crashes or white‑screens may occur.
On a 4 GB device, the foreground app was killed after allocating about 3864316 KB (~3.7 GB) :
<6>[122969.200223] lowmemorykiller: Killing 'raoke.memoryApp' (21760) (tgid 21760), adj 0,
<6>[122969.200223] to free 3864316kB on behalf of 'UsbFfs-worker' (25160) because
<6>[122969.200223] cache 72088kB is below limit 73728kB for oom score 0
<6>[122969.200223] Free memory is -35644kB above reserved.3. Address Space Layout
Android apps are forked from the zygote process using Copy‑On‑Write . The virtual address space includes:
main space : 1 GB starting at 0x12c00000 , used for Java heap and VM objects.
image space : system boot images.
zygote space / non‑moving space : shared classes and resources, not subject to GC.
others : ASLR‑distributed regions.
ffffffff +---------------------------+
| |
+---------------------------+
| stack |
+---------------------------+
| |
| |
z z
| |
| |
+---------------------------+
| no moving space (62+M) |
+---------------------------+
| zygote space (1+M) |
+---------------------------+
| image space |
+---------------------------+
| |
52C0000 +---------------------------+
| |
| main space 2 (512M) |
+---------------------------+
32C0000 +---------------------------+
| |
| main space 1 (512M) |
+---------------------------+
12C0000 +---------------------------+
| |
| |
00000000 +---------------------------+Sample memory usage (top 20 entries, unit KB):
VmSize PSS Dirty Swap Mapping
------ ------ ----- ----- ------
1048576 380 380 0 [anon:dalvik-main space (region space)]
133120 0 0 0 [anon:libwebview reservation]
110144 216 216 16 [anon]
98304 16 8 0 jit-cache (deleted)
63760 92 92 0 [anon:dalvik-non moving space]
... (other entries omitted for brevity)4. Virtual Memory Analysis
4.1 smaps introduction
Virtual memory usage can be inspected via /proc/ /status (field VmSize ) or more detailed via /proc/ /smaps . Tools like pmap provide a concise view.
Address Kbytes PSS Dirty Swap Mode Mapping
0000000012c00000 256 4 4 0 rw--- [anon:dalvik-main space (region space)]
000000001fb40000 836352 0 0 0 rw--- [anon:dalvik-main space (region space)]
0000000070b9c000 1964 771 744 56 rw--- boot.art
... (other lines omitted)Fields:
Kbytes : virtual memory size.
PSS : proportional set size (physical memory, shared counted proportionally).
Dirty : dirty pages.
Mapping : file or anonymous mapping name.
4.2 Memory Increment Analysis
In the live‑room scenario of the Karaoke app, entering and leaving a room causes memory increments. The steps are:
Capture memory maps before and after using pmap (saved as map1.txt and map2.txt ).
Remove duplicate lines and merge entries with the same Mapping into merge1.txt and merge2.txt .
Calculate per‑mapping increments between the merged files.
Summarize the results (see screenshot in the original article).
Example of merged data:
Kbytes PSS Dirty Swap Mode Mapping
53504 10588 10588 0 rw--- [anon:dalvik-main space (region space)]Sample Kotlin code used for classification:
private fun analysisLineType(lines: ArrayList
) {
lines.forEach {
it.type = when {
it.mapping.startsWith("[anon:dalvik-alloc space") ||
it.mapping.startsWith("[anon:dalvik-main space") ||
it.mapping.startsWith("[anon:dalvik-large object space") ||
it.mapping.startsWith("[anon:dalvik-non moving space") ||
it.mapping.startsWith("[anon:dalvik-zygote space") ||
it.mapping.startsWith("[anon:dalvik-free list large object space") -> "[1]dalvik"
it.mapping.endsWith(".so") -> "[8].so"
it.mapping.endsWith(".art") || it.mapping.endsWith(".art]") -> "[e].art"
it.mapping == "[anon]" -> "[f]other-mmap"
// ... other branches omitted
}
}
}The analysis revealed that loading libYTCommon.so consumes 304 KB of virtual memory (288 KB of clean pages). This library is for image processing and is unnecessary for live‑room playback, indicating an inefficiency.
5. Conclusion
Virtual memory greatly simplifies application development and process management. However, 32‑bit Android apps are constrained by a 4 GB address space, which can become a bottleneck leading to crashes or white screens. This article provided a brief overview of virtual memory size, layout, and content analysis, hoping to inspire further investigation.
QQ Music / Karaoke recruitment for Android/iOS client developers – send resume to [email protected]
Tencent Music Tech Team
Public account of Tencent Music's development team, focusing on technology sharing and communication.
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.