在Linux系统中,内存分配主要通过内核机制和用户空间库函数实现。以下是详细的方法步骤和说明:
#include <stdlib.h>
// 动态分配内存(未初始化)
void *malloc(size_t size);
// 分配并初始化为0
void *calloc(size_t nmemb, size_t size);
// 调整已分配内存大小
void *realloc(void *ptr, size_t size);
// 释放内存
void free(void *ptr);
示例:
int *arr = malloc(10 * sizeof(int)); // 分配10个int的空间
free(arr); // 释放内存
#include <stdlib.h>
void *aligned_alloc(size_t alignment, size_t size); // C11标准
posix_memalign(void **memptr, size_t alignment, size_t size); // POSIX标准
#include <sys/mman.h>
void *mmap(void *addr, size_t length, int prot, int flags, int fd, off_t offset);
int munmap(void *addr, size_t length);
示例:
void *mem = mmap(NULL, 4096, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANONYMOUS, -1, 0);
munmap(mem, 4096); // 释放
#include <linux/slab.h>
void *kmalloc(size_t size, gfp_t flags); // 分配物理连续的内存
void kfree(const void *objp);
常用flags
:
- GFP_KERNEL
:普通优先级,可能触发回收。
- GFP_ATOMIC
:原子分配,禁止休眠。
#include <linux/gfp.h>
struct page *alloc_pages(gfp_t gfp_mask, unsigned int order); // 分配2^order个连续页
void *page_address(struct page *page); // 获取页的虚拟地址
kmem_cache_create() // 创建专用缓存
kmem_cache_alloc() // 从缓存分配
kmem_cache_free() // 释放到缓存
#include <linux/vmalloc.h>
void *vmalloc(unsigned long size);
void vfree(const void *addr);
内存池(Memory Pool)
mempool
)。OOM(Out-of-Memory)处理
/proc/sys/vm/overcommit_memory
调整策略:
0
:启发式overcommit(默认)1
:总是overcommit2
:禁止overcommit透明大页(THP)
echo always > /sys/kernel/mm/transparent_hugepage/enabled
查看内存使用
free -h # 查看系统内存
vmstat 1 # 监控内存和交换
cat /proc/meminfo # 详细内存信息
检测内存泄漏
valgrind --leak-check=yes ./program
kmemleak
工具手动释放缓存
sync; echo 3 > /proc/sys/vm/drop_caches # 释放PageCache/Slab
errno
(如ENOMEM
)。NULL
或触发OOM Killer。kmalloc
(物理连续) vs vmalloc
(虚拟连续)GFP_KERNEL
(可休眠) vs GFP_ATOMIC
(原子操作)通过合理选择分配方法,可以优化性能和资源利用率。