While the Binder driver is incredibly fast for sending small messages and method calls between processes, it has a strict transaction limit (historically around 1MB).
If a music app needs to send a 10MB uncompressed audio buffer to the audioserver daemon, it cannot push it through a Binder transaction. To solve this, Android engineers created Ashmem (Anonymous Shared Memory).
What is Ashmem?
Ashmem is another custom Android kernel driver, exposed to user space via the /dev/ashmem character device.
It allows two completely isolated processes to share a block of physical RAM.
The Ashmem Flow
- Creation: App A opens
/dev/ashmemand requests a 10MB region using anioctlcommand. The kernel allocates the physical memory and returns a standard Linux File Descriptor (FD) representing that block. - Passing the FD: App A sends this File Descriptor to the
audioserverprocess using a tiny 1KB Binder transaction. Binder is specifically designed to safely translate File Descriptors between isolated processes. - Mapping: The
audioserverreceives the FD and uses themmap()system call. The kernel maps the exact same 10MB block of physical RAM into theaudioserver's virtual memory space. - Zero-Copy: App A can now write audio data to the memory, and the
audioservercan read it instantly. There are zero copies happening in the background!
// Simplified C code for creating an Ashmem region
int fd = open("/dev/ashmem", O_RDWR);
ioctl(fd, ASHMEM_SET_NAME, "my_audio_buffer");
ioctl(fd, ASHMEM_SET_SIZE, 10 * 1024 * 1024); // 10MB
// Map it into the app's memory to write data
void *buffer = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED, fd, 0);
Ashmem vs Standard POSIX Shared Memory
Standard Linux already has a shared memory system (POSIX shm). Why did Google write a custom driver for Android?
The answer lies in the Android Low Memory Killer (LMK). Standard Linux shared memory is "sticky." If an app crashes and forgets to explicitly free the shared memory, that memory is permanently leaked until the phone reboots.
Ashmem integrates deeply with the Android memory management subsystem:
- Ashmem regions use reference counting.
- If App A and
audioserverboth crash or are killed by the LMK daemon, the kernel instantly detects that all file descriptors pointing to that Ashmem region are closed, and it automatically reclaims the 10MB of physical RAM. - It also allows apps to mark regions as "purgeable," meaning the kernel can steal the memory in a low-RAM emergency without asking for permission.
// Marking an ashmem region as purgeable by the kernel
ioctl(fd, ASHMEM_PIN, &pin_struct); // Pin it when using it
ioctl(fd, ASHMEM_UNPIN, &pin_struct); // Unpin it (purgeable) when not using it
Note: In modern Android versions, Google is slowly deprecating the custom /dev/ashmem driver in favor of the standardized Linux memfd_create system call, which has finally gained similar features.