Glibc内存管理--ptmalloc2源代码分析(三十一)

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()函数执行实际的释放工作,然后对分配区解锁。
}
 

猜你喜欢

转载自mqzhuang.iteye.com/blog/1064961