什么是内存泄漏?
内存泄漏——chunk永远回不来了
今天简单说一说内存泄漏。
这个Bug看起来简单,但背后的机制不简单。表面现象
void process_data() {
char* buffer = (char*)malloc(1024);
// ... 处理数据
// 忘记 free(buffer)
}
每次调用这个函数,就泄漏1024字节。调用1万次,就是10MB。
你可能会想:"不就是忘记free吗?记得free不就行了?"
没这么简单。真正的问题在于:一旦malloc出去的内存没有被free,这块内存在进程生命周期内就再也回不来了。
底层原理
要理解内存泄漏的底层机制,得先搞懂malloc是怎么管理内存的。
glibc的malloc(ptmalloc2)管理内存分两种方式:
- 小内存(< 128KB):通过brk/sbrk系统调用在heap区域分配malloc向OS申请一大块内存,然后切分成一个个chunk每个chunk有元数据区,记录大小、是否空闲、前后指针free时只是把chunk标记为"空闲",加入空闲链表(bins),内存并不归还给OS这些chunk可以被重复利用
- 大内存(≥ 128KB,即MMAP_THRESHOLD):通过mmap直接分配malloc直接调用mmap向OS申请独立内存区域free时调用munmap,立即归还给OS,进程RSS会立即下降这个阈值可以通过mallopt(M_MMAP_THRESHOLD, value)调整
关键来了:
对于小内存,free只是把chunk标记为空闲,内存并没有还给操作系统。这意味着什么?如果你频繁malloc/free小块内存(比如每次1KB),即使free了,进程的内存占用依然很高,这些内存会被malloc重复利用,但不会还给系统(除非调用malloc_trim主动收缩heap)。但如果你malloc了1GB内存(远超128KB),free后进程内存占用会下降,因为大内存会通过munmap立即归还。
所以,内存泄漏的真正危害是:可用的chunk越来越少,最终malloc找不到合适的chunk,只能不断向系统申请新内存,直到OOM。
- 上一篇:如何在windows中调用命令
- 下一篇:02编程是 一门技术
评论已关闭