5.8 内存释放free
5.8.1 public_fREe()
public_fREe() 函数的源代码如下:
void public_fREe(Void_t* mem) { mstate ar_ptr; mchunkptr p; /* chunk corresponding to mem */ void (*hook) (__malloc_ptr_t, __const __malloc_ptr_t) = force_reg (__free_hook); if (__builtin_expect (hook != NULL, 0)) { (*hook)(mem, RETURN_ADDRESS (0)); return; } 如果存在free的hook函数,执行该hook函数返回,free的hook函数主要用于创建新线程使用或使用用户提供的free函数。 if (mem == 0) /* free(0) has no effect */ return; p = mem2chunk(mem); free NULL指针直接返回,然后根据内存指针获得chunk的指针。 #if HAVE_MMAP if (chunk_is_mmapped(p)) /* release mmapped memory. */ { /* see if the dynamic brk/mmap threshold needs adjusting */ if (!mp_.no_dyn_threshold && p->size > mp_.mmap_threshold && p->size <= DEFAULT_MMAP_THRESHOLD_MAX) { mp_.mmap_threshold = chunksize (p); mp_.trim_threshold = 2 * mp_.mmap_threshold; } munmap_chunk(p); return; } #endif 如果当前free的chunk是通过mmap()分配的,调用munmap_chunk()函数unmap本chunk。munmap_chunk()函数调用munmap()函数释放mmap()分配的内存块。同时查看是否开启了mmap分配阈值动态调整机制,默认是开启的,如果当前free的chunk的大小大于设置的mmap分配阈值,小于mmap分配阈值的最大值,将当前chunk的大小赋值给mmap分配阈值,并修改mmap收缩阈值为mmap分配阈值的2倍。默认情况下mmap分配阈值与mmap收缩阈值相等,都为128KB。 ar_ptr = arena_for_chunk(p); 根据chunk指针获得分配区的指针。 #ifdef ATOMIC_FASTBINS _int_free(ar_ptr, p, 0); 如果开启了ATOMIC_FASTBINS优化,不需要对分配区加锁,调用_int_free()函数执行实际的释放工作。 #else # if THREAD_STATS if(!mutex_trylock(&ar_ptr->mutex)) ++(ar_ptr->stat_lock_direct); else { (void)mutex_lock(&ar_ptr->mutex); ++(ar_ptr->stat_lock_wait); } # else (void)mutex_lock(&ar_ptr->mutex); # endif _int_free(ar_ptr, p); (void)mutex_unlock(&ar_ptr->mutex); #endif 如果没有开启了ATOMIC_FASTBINS优化,或去分配区的锁,调用_int_free()函数执行实际的释放工作,然后对分配区解锁。 }