Releases: pboyd/malloc
v1.2.1
VirtBackend: Addr and Release (breaking change)
VirtBackend now returns *VirtReservationBackend instead of ArenaBackend, exposing two new methods to callers.
Addr() returns the base address of the reserved region. Use it to verify alignment or placement requirements before committing to the arena:
backend, err := malloc.VirtBackend(64 << 20)
if err != nil {
log.Fatal(err)
}
if backend.Addr() % alignment != 0 {
backend.Release()
log.Fatal("unsuitable address")
}
arena := malloc.NewArena(malloc.Backend(backend))Release() frees the entire reservation. Call it when the address returned by Addr is unsuitable, or to free the backend's memory independently of the arena.
Migration
If you stored the result of VirtBackend as an ArenaBackend interface, update the declaration to the concrete type:
// Before
var backend malloc.ArenaBackend
backend, err = malloc.VirtBackend(size)
// After
backend, err := malloc.VirtBackend(size)v1.2.0
VirtBackend
v1.2.0 adds VirtBackend, a fixed-capacity backend that reserves a contiguous virtual address range at startup and commits physical memory on demand.
backend, err := malloc.VirtBackend(64 << 20) // reserve 64 MiB
if err != nil {
log.Fatal(err)
}Each Grow call extends the committed region in place, so all allocations share the same base address. This makes VirtBackend a good fit for arenas where you know the maximum size upfront and need pointers to remain valid after the arena grows. When committed memory reaches the reserved capacity, Grow returns ErrOutOfMemory.
On Unix, VirtBackend reserves address space with PROT_NONE and commits pages via mprotect. On Windows, it uses MEM_RESERVE followed by MEM_COMMIT. VirtBackend implements ProtectedArenaBackend.
MmapBackend options (breaking change)
MmapBackend now accepts variadic BackendOpt options instead of positional prot and flags integers.
Before:
backend := malloc.MmapBackend(syscall.PROT_EXEC, 0)After:
backend := malloc.MmapBackend(malloc.MmapProt(syscall.PROT_EXEC))A new MmapAddr option requests a preferred mapping address from the kernel. These same options work with VirtBackend.
Bug fixes
- Fixed exec protection flag for
MmapBackendon Windows.
v1.1.0
Memory Protection Control
This release adds memory protection control through the ProtectedArenaBackend interface. Use MmapBackend.Protect() to change page permissions on memory-mapped allocations.
The protection value passes directly to the underlying system call (mprotect on Unix, VirtualProtect on Windows), giving you full control over page permissions.
BSD Support
Builds now succeed on FreeBSD, OpenBSD, and NetBSD. Cross-compilation tests verify compatibility with these platforms.
What's Changed
- feat: add option to change protections on mmap pages by @pboyd in 919d615
- fix: Verify that compilation works for a few BSD variants by @pboyd in 401116a
Full Changelog: v1.0.0...v1.1.0
v1.0.0
Release Notes: v1.0.0
malloc v1.0.0 marks the first stable release version. The package now supports concurrent access, dynamic memory growth, and memory-mapped allocation.
Breaking Changes
Function signatures changed:
// Old (v0.10.0)
func NewArena(size uint64) *Arena
func NewArenaAt[T any](buf []T) *Arena
// New (v1.0.0)
func NewArena(size uint64, opts ...Opt) *Arena
func NewArenaAt[T any](buf []T, opts ...Opt) *ArenaExisting code continues to work without changes. The new optional parameters add configuration without breaking compatibility.
New Features
Thread-Safe Arenas
Arenas now protect concurrent access with a mutex. Multiple goroutines can allocate and free memory simultaneously.
arena := malloc.NewArena(64 * 1024)
// Safe to call from multiple goroutines
go func() {
p, _ := malloc.Malloc[int](arena)
malloc.Free(arena, p)
}()Dynamic Growth
Arenas grow automatically when they run out of space. The backend determines how growth occurs.
// Starts small, grows as needed
arena := malloc.NewArena(1024, malloc.Backend(malloc.SliceBackend))Memory-Mapped Allocation
The MmapBackend allocates memory through mmap(2) on Unix or VirtualAlloc on Windows. This keeps allocated memory outside the Go heap.
// Allocate 4KB via mmap
arena := malloc.NewArena(4096, malloc.Backend(malloc.MmapBackend(0, 0)))Platforms: Linux, macOS, Windows
Improvements
- Improved error detection for double-free bugs
- Added GitHub Actions CI across Go 1.25, 1.26 and all supported platforms
Known Limitations
- The mmap backend does not support BSD systems (except Darwin)
- Growth performance depends on the backend implementation
- Minimum allocation size remains 16 bytes
Migration Guide
From v0.10.0
No code changes required. The API remains compatible.
To opt into new features:
// Enable growth
arena := malloc.NewArena(1024, malloc.Backend(malloc.SliceBackend))
// Use mmap
arena := malloc.NewArena(4096, malloc.Backend(malloc.MmapBackend(0, 0)))Requirements
- Go 1.25 or later
- For mmap support: Linux, macOS, or Windows
v0.10.0
Full Changelog: v0.9.0...v0.10.0