Fundamentals 22 min read

How eBPF Can Tackle Linux Memory Fragmentation and Boost Android Performance

This article explains the problem of internal and external memory fragmentation in Linux systems, introduces eBPF as a powerful tracing tool, and provides step‑by‑step guidance for building, loading, and running eBPF programs to analyze and mitigate fragmentation on both Linux and Android platforms.

Deepin Linux
Deepin Linux
Deepin Linux
How eBPF Can Tackle Linux Memory Fragmentation and Boost Android Performance

Memory management is critical in computer systems, and memory fragmentation—both internal and external—reduces utilization, increases latency, and can cause allocation failures.

eBPF Technology Overview

eBPF (Extended Berkeley Packet Filter) originated as a network packet filter and has evolved into a general‑purpose in‑kernel virtual machine that can load custom programs without modifying kernel source or rebooting, enabling precise tracing of allocation and release events.

eBPF Origins and Evolution

Originally created in 1992 as BPF for fast packet filtering, it was extended in 2014 to support a wide range of kernel programming tasks.

How eBPF Works

Developers write eBPF code in C, compile it with clang to bytecode, and load it into the kernel where a verifier checks safety before JIT‑compiling to native code. Programs attach to kernel hooks (kprobes, tracepoints, etc.) and can read or write data via maps.

Unique Advantages

Runs in kernel space, avoiding costly user‑kernel context switches.

Strict verification ensures safety and stability.

Flexible map types enable efficient data sharing between kernel and user space.

Practical eBPF Setup

To use eBPF, compile the kernel with BPF support, install BCC tools, and ensure the kernel version is ≥4.9.

Building and Running Samples

<code>$ cd /tmp
apt -y download libcrypt1
dpkg-deb -x libcrypt1_1%3a4.4.25-2_amd64.deb .
cp -av lib/x86_64-linux-gnu/* /lib/x86_64-linux-gnu/
apt -y --fix-broken install</code>

Compile the kernel, enable BPF options in .config, install required packages (dwarves, libssl-dev), and build the helloworld example.

Writing a Simple Memory‑Tracing eBPF Program

<code>#include &lt;uapi/linux/ptrace.h&gt;
struct alloc_info { u32 pid; u64 size; u64 timestamp; char comm[TASK_COMM_LEN]; };
BPF_HASH(alloc_map, u64, struct alloc_info);
BPF_PERF_OUTPUT(free_events);
int kprobe__kmalloc(struct pt_regs *ctx, size_t size) { u64 ip = bpf_get_current_retval(ctx); if (!ip) return 0; struct alloc_info info = {};
info.pid = bpf_get_current_pid_tgid() >> 32; info.size = size; info.timestamp = bpf_ktime_get_ns(); bpf_get_current_comm(&amp;info.comm, sizeof(info.comm)); alloc_map.update(&amp;ip, &amp;info); return 0; }
int kprobe__kfree(struct pt_regs *ctx) { u64 ip = PT_REGS_PARM1(ctx); if (!ip) return 0; struct alloc_info *info = alloc_map.lookup(&amp;ip); if (!info) return 0; struct { u32 pid; u64 timestamp; char comm[TASK_COMM_LEN]; } free_info = {};
free_info.pid = info-&gt;pid; free_info.timestamp = bpf_ktime_get_ns(); __builtin_memcpy(&amp;free_info.comm, &amp;info-&gt;comm, sizeof(free_info.comm));
free_events.perf_submit(ctx, &amp;free_info, sizeof(free_info)); alloc_map.delete(&amp;ip); return 0; }</code>

A Python script using BCC loads the program, opens the perf buffer, and prints PID, command name, and free timestamps.

<code>from bcc import BPF
import time
b = BPF(src_file="memory_trace.c")

def print_free_event(cpu, data, size):
    event = b["free_events"].event(data)
    print(f"PID: {event.pid}, COMM: {event.comm.decode('utf-8')}, FREE_TIME: {event.timestamp/1e9:.6f}s")

b["free_events"].open_perf_buffer(print_free_event)
print("Tracing memory allocations and frees... Ctrl+C to end.")
while True:
    b.perf_buffer_poll()
    time.sleep(1)
</code>

eBPF on Android

Android integrates eBPF compilation via android.bp . Compiled *.o files are placed in /system/etc/bpf and loaded at boot by bpfloader , exposing maps and programs under /sys/fs/bpf .

Typical workflow: enable JIT ( /proc/sys/net/core/bpf_jit_enable ), push eBPF objects, restart, and use user‑space tools to read maps and display per‑PID syscall counts.

Kernel Tuning Together with eBPF

Parameters such as swappiness and overcommit_memory influence memory pressure and fragmentation. Real‑time eBPF metrics help decide optimal values, creating a feedback loop between tracing and kernel parameter adjustment.

androideBPFLinux kernelmemory fragmentationBPFkernel debuggingperformance tracing
Deepin Linux
Written by

Deepin Linux

Research areas: Windows & Linux platforms, C/C++ backend development, embedded systems and Linux kernel, etc.

0 followers
Reader feedback

How this landed with the community

login Sign in to like

Rate this article

Was this worth your time?

Sign in to rate
Discussion

0 Comments

Thoughtful readers leave field notes, pushback, and hard-won operational detail here.