gVisor - MemoryFile
MemoryFile is a gVisor-specific internal abstraction.
In the gVisor codebase (written in Go under pkg/sentry/memmap), MemoryFile is a core abstraction used by the Sentry kernel to represent a contiguous, memory-backed storage object that can be mapped into the virtual address space of sandboxed application processes.
Why MemoryFile Exists in gVisor
In a standard Linux kernel, when processes allocate anonymous memory (malloc, mmap(MAP_ANONYMOUS)), shared memory (shm_open, memfd_create), or tmpfs files, the host kernel manages physical RAM pages using its internal page allocator (struct page) and swap subsystem.
However, gVisor's Sentry runs entirely in userspace as a Go application. It cannot manage physical RAM hardware directly. Instead, to give sandboxed applications memory, gVisor must ask the host Linux kernel for underlying memory.
MemoryFile is gVisor's internal wrapper around host-provided virtual memory file descriptors—specifically anonymous memory files created on the host using memfd_create() or host tmpfs files.
┌─────────────────────────────────────────────────────────┐
│ Sandboxed App Virtual Address Space │
│ (e.g., App Heap, Anonymous mmap, shared memory) │
└────────────────────────────┬────────────────────────────┘
│
▼ gVisor Memory Management
┌─────────────────────────────────────────────────────────┐
│ gVisor Platform Engine │
│ (Systrap / KVM Memory Mapping) │
└────────────────────────────┬────────────────────────────┘
│
▼
┌─────────────────────────────────────────────────────────┐
│ gVisor MemoryFile │
│ • Tracks Allocation/Deallocation Ranges │
│ • Manages File Offsets (FileRange) │
│ • Tracks Memory Reference Counts │
└────────────────────────────┬────────────────────────────┘
│ backed by host file descriptor
▼
┌─────────────────────────────────────────────────────────┐
│ Host Linux Kernel │
│ memfd_create() / Host tmpfs File │
└─────────────────────────────────────────────────────────┘
Key Responsibilities of MemoryFile
Inside pkg/sentry/memmap/memory_file.go, MemoryFile manages several critical duties:
A. Sub-Allocation of Host memfd Space
Rather than making a separate host system call (like memfd_create) for every small mmap or malloc request inside the container, gVisor allocates large backing host memory files (memfd_create) and uses MemoryFile to carve up offset ranges (represented as memmap.FileRange) within those files.
B. Translation Between App Memory and Host Memory
When an application inside the container requests memory:
- The Sentry allocates a range inside its internal
MemoryFile. - The Sentry maps that host file offset into the Sentry's own address space or guest page tables (
KVM_SET_USER_MEMORY_REGIONorsystrapshared memory mappings). - The application thread receives a virtual address corresponding to that slice of the
MemoryFile.
C. Reference Counting & Life Cycle Management
MemoryFile tracks page usage. When application memory is unmapped (munmap), MemoryFile handles reclaiming or freeing ranges using host system calls like fallocate(FALLOC_FL_PUNCH_HOLE) on the underlying host memfd. Punching holes releases physical RAM back to the host Linux kernel immediately while maintaining the file's logical size.
Where MemoryFile is Used in gVisor
MemoryFile backs almost all volatile memory operations inside the sandbox:
- Anonymous Application Memory:
mmap(MAP_ANONYMOUS), heap expansions (brk), and application thread stacks. - Internal Container
tmpfs: Files stored in the container's volatile/tmportmpfsmounts. - Shared Memory Systems: POSIX shared memory (
shm_open) and System V shared memory (shmget). - Copy-on-Write (COW) Private Mappings: Backing private writable memory pages created when an application forks.
Summary
MemoryFile is gVisor's internal memory management primitive that bridges the gap between sandboxed application memory requests and host Linux memory. It wraps host anonymous memory file descriptors (memfd_create) and manages offset allocation, page reference counting, and physical RAM reclamation (FALLOC_FL_PUNCH_HOLE) for the Sentry.