malloc, jemalloc, and mimalloc are memory allocators used in software development to dynamically allocate and deallocate memory on the heap, managed by the C runtime library, not the kernel directly:

  • The heap grows and shrinks dynamically, and memory allocation is abstracted via functions
  • Internally, the heap interacts with the kernel using syscalls like brk or mmap.
  • Fragmentation and runtime overhead are managed by the allocator implementation (e.g., glibc malloc, jemalloc, or tcmalloc).

In contrast, nmap bypasses the heap and directly allocates memory pages from the kernel:

malloc

malloc is a standard library function provided in both C and C++, defined in <stdlib.h> for C and <cstdlib> for C++. It allocates a specified number of bytes and returns a pointer to the allocated memory. The memory is not initialized, meaning its contents are undefined. Additional related functions include calloc, which initializes the memory to zero, and realloc, which resizes previously allocated memory. Internally, both calloc and realloc rely on malloc for their operations.

The implementation of malloc depends on the platform. On Linux, glibc malloc manages memory through sbrk, which expands the heap, or mmap, which is used for large allocations. On Windows, HeapAlloc serves as the implementation. While malloc is general-purpose and compatible across systems, it may suffer in highly multithreaded scenarios or workloads with significant memory fragmentation.

#include <stdlib.h>
#include <stdio.h>
 
int main() {
    int *arr = (int *)malloc(10 * sizeof(int));  // Allocates memory for 10 integers
    if (arr) {
        for (int i = 0; i < 10; i++) arr[i] = i;  // Initialize values
        for (int i = 0; i < 10; i++) printf("%d ", arr[i]);  // Print values
        free(arr);  // Deallocate memory
    }
    return 0;
}

Jason Evans Malloc (jemalloc)

jemalloc is a high-performance memory allocator designed to address issues like fragmentation and poor multithreaded performance seen in malloc. It achieves this by introducing thread-specific arenas, where each thread has its own memory management area, significantly reducing contention during concurrent allocations. This feature makes it especially effective in performance-critical applications like databases (e.g., Redis and MongoDB).

A standout feature of jemalloc is its ability to handle workloads with varied allocation patterns while minimizing long-term fragmentation. It also provides diagnostic tools to help developers debug memory leaks and track memory usage. However, jemalloc requires explicit linking (-ljemalloc), and the additional configuration and binary size may not be necessary for simpler applications.

#include <jemalloc/jemalloc.h>
#include <stdio.h>
 
int main() {
    int *arr = (int *)malloc(10 * sizeof(int));  // jemalloc replaces malloc
    if (arr) {
        for (int i = 0; i < 10; i++) arr[i] = i;
        for (int i = 0; i < 10; i++) printf("%d ", arr[i]);
        free(arr);  // jemalloc handles cleanup
    }
    return 0;
}

To use jemalloc, link it explicitly during compilation:

gcc -o program program.c -ljemalloc

Microsoft Malloc (mimalloc)

mimalloc is a modern memory allocator developed by Microsoft Research. It focuses on being lightweight and fast, with optimizations for cache locality and multithreaded workloads. It uses per-thread heaps to reduce contention and incorporates randomized allocation patterns to enhance memory safety. mimalloc is particularly effective for workloads with frequent small allocations and deallocations.

Like jemalloc, mimalloc can be used as a drop-in replacement for malloc. It also provides its own API for advanced use cases, such as allocating memory explicitly through mi_malloc and freeing it with mi_free.

#include <mimalloc.h>
#include <stdio.h>
 
int main() {
    int *arr = (int *)mi_malloc(10 * sizeof(int));  // Use mimalloc API
    if (arr) {
        for (int i = 0; i < 10; i++) arr[i] = i;
        for (int i = 0; i < 10; i++) printf("%d ", arr[i]);
        mi_free(arr);  // Deallocate memory using mimalloc
    }
    return 0;
}

To use mimalloc, link it explicitly during compilation:

gcc -o program program.c -lmimalloc

For projects, you can also configure mimalloc to override malloc globally, providing compatibility with existing codebases while leveraging its performance benefits.