一、5种malloc方法

1)tcache_alloc_small

2)arena_malloc_small

3)tcache_alloc_large

4)arena_malloc_large

5)huge_malloc

//written in jemalloc_internal.h file
imalloct(size_t size, bool try_tcache, arena_t *arena)
{
assert(size != ); if (size <= arena_maxclass)
return (arena_malloc(arena, size, false, try_tcache));
else
return (huge_malloc(size, false, huge_dss_prec_get(arena)));
}
JEMALLOC_ALWAYS_INLINE void *
imalloc(size_t size)
{ return (imalloct(size, true, NULL));
}
//written in arena.h
JEMALLOC_ALWAYS_INLINE void *
arena_malloc(arena_t *arena, size_t size, bool zero, bool try_tcache)
{
tcache_t *tcache; assert(size != );
assert(size <= arena_maxclass); if (size <= SMALL_MAXCLASS) {
if (try_tcache && (tcache = tcache_get(true)) != NULL)
return (tcache_alloc_small(tcache, size, zero));
else {
return (arena_malloc_small(choose_arena(arena), size,
zero));

}
} else {
/*
* Initialize tcache after checking size in order to avoid
* infinite recursion during tcache initialization.
*/
if (try_tcache && size <= tcache_maxclass && (tcache =
tcache_get(true)) != NULL)
return (tcache_alloc_large(tcache, size, zero));
else {
return (arena_malloc_large(choose_arena(arena), size,
zero));

}
}
}

 二、malloc时选择arena的机制

1)先用arenas_tsd_get获得线程绑定变量arena;

2)如果1)获得值为null,则扫描arenas数组,找到threads number为0或者最小的未卸载的arena;

3)如果2)中扫描发现存在null插槽,则需要调用arenas_extend进行初始化null插槽;

4)调用arenas_tsd_set设置线程绑定比变量arena。

//详细见jemalloc.c中函数
arena_t *choose_arena_hard(void)

三、arenas_extend处理过程 

在choose_arena处理过程中,找到一个null空arena后,需要对该arena做初始化,即调用arenas_extend函数,它的处理过程如下:

1)base_alloc arena_t对象;

2)arena_new arena_t对象;

arena_t *arenas_extend(unsigned ind)
{
arena_t *ret; ret = (arena_t *)base_alloc(sizeof(arena_t));
if (ret != NULL && arena_new(ret, ind) == false) {
arenas[ind] = ret;
return (ret);
}
/* Only reached if there is an OOM error. */ /*
* OOM here is quite inconvenient to propagate, since dealing with it
* would require a check for failure in the fast path. Instead, punt
* by using arenas[0]. In practice, this is an extremely unlikely
* failure.
*/
malloc_write("<jemalloc>: Error initializing arena\n");
if (opt_abort)
abort(); return (arenas[]);
}

四、base_alloc处理过程

1)数据对齐CACHELINE_CEILING,即64位对齐(8字节);

2)调用base_pages_alloc申请足够内存,从而调用chunk_alloc申请chunk对象;

3)chunk_alloc过程:如果采用dss优先的申请方式,则尝试sbrk这种方式申请,再尝试mmap这种方式;反之,则反序。

chunk_alloc(size_t size, size_t alignment, bool base, bool *zero,
dss_prec_t dss_prec)
{
void *ret; assert(size != );
assert((size & chunksize_mask) == );
assert(alignment != );
assert((alignment & chunksize_mask) == ); /* "primary" dss. */
if (config_dss && dss_prec == dss_prec_primary) {
if ((ret = chunk_recycle(&chunks_szad_dss, &chunks_ad_dss, size,
alignment, base, zero)) != NULL)
goto label_return;
if ((ret = chunk_alloc_dss(size, alignment, zero)) != NULL)
goto label_return;
}
/* mmap. */
if ((ret = chunk_recycle(&chunks_szad_mmap, &chunks_ad_mmap, size,
alignment, base, zero)) != NULL)
goto label_return;
if ((ret = chunk_alloc_mmap(size, alignment, zero)) != NULL)
goto label_return;
/* "secondary" dss. */
if (config_dss && dss_prec == dss_prec_secondary) {
if ((ret = chunk_recycle(&chunks_szad_dss, &chunks_ad_dss, size,
alignment, base, zero)) != NULL)
goto label_return;
if ((ret = chunk_alloc_dss(size, alignment, zero)) != NULL)
goto label_return;
}
/* All strategies for allocation failed. */
ret = NULL;
label_return:
if (ret != NULL) {
if (config_ivsalloc && base == false) {
if (rtree_set(chunks_rtree, (uintptr_t)ret, )) {
chunk_dealloc(ret, size, true);
return (NULL);
}
}
if (config_stats || config_prof) {
bool gdump;
malloc_mutex_lock(&chunks_mtx);
if (config_stats)
stats_chunks.nchunks += (size / chunksize);
stats_chunks.curchunks += (size / chunksize);
if (stats_chunks.curchunks > stats_chunks.highchunks) {
stats_chunks.highchunks =
stats_chunks.curchunks;
if (config_prof)
gdump = true;
} else if (config_prof)
gdump = false;
malloc_mutex_unlock(&chunks_mtx);
if (config_prof && opt_prof && opt_prof_gdump && gdump)
prof_gdump();
}
if (config_valgrind)
VALGRIND_MAKE_MEM_UNDEFINED(ret, size);
} return ret;
}

jemalloc源码结构分析(一):内存申请处理过程的更多相关文章

  1. jemalloc源码结构分析(三):arena_malloc_small内存分布

    在arena_s结构中,由NBINS数组将bin按照不同规模等级分别存储,每一个等级对应一颗run树,即一颗以chunk_map_t为节点的红黑树,而这些chunk_map_t节点实际分布于各个chu ...

  2. jemalloc源码结构分析(二):CPU字节对齐算法

    在调用arena_malloc_small过程中,要根据申请内存大小,进行对齐计算,然后分配一个整块儿.算法如下: 1)定义一个SIZE_CLASSES宏,它主要用于生成后面两个表,small_siz ...

  3. Memcached源码分析之内存管理

    先再说明一下,我本次分析的memcached版本是1.4.20,有些旧的版本关于内存管理的机制和数据结构与1.4.20有一定的差异(本文中会提到). 一)模型分析在开始解剖memcached关于内存管 ...

  4. v76.01 鸿蒙内核源码分析(共享内存) | 进程间最快通讯方式 | 百篇博客分析OpenHarmony源码

    百篇博客分析|本篇为:(共享内存篇) | 进程间最快通讯方式 进程通讯相关篇为: v26.08 鸿蒙内核源码分析(自旋锁) | 当立贞节牌坊的好同志 v27.05 鸿蒙内核源码分析(互斥锁) | 同样 ...

  5. 老李推荐:第8章1节《MonkeyRunner源码剖析》MonkeyRunner启动运行过程-运行环境初始化

    老李推荐:第8章1节<MonkeyRunner源码剖析>MonkeyRunner启动运行过程-运行环境初始化   首先大家应该清楚的一点是,MonkeyRunner的运行是牵涉到主机端和目 ...

  6. Flink 源码解析 —— JobManager 处理 SubmitJob 的过程

    JobManager 处理 SubmitJob https://t.zsxq.com/3JQJMzZ 博客 1.Flink 从0到1学习 -- Apache Flink 介绍 2.Flink 从0到1 ...

  7. Flink 源码解析 —— TaskManager 处理 SubmitJob 的过程

    TaskManager 处理 SubmitJob 的过程 https://t.zsxq.com/eu7mQZj 博客 1.Flink 从0到1学习 -- Apache Flink 介绍 2.Flink ...

  8. 老李推荐:第8章7节《MonkeyRunner源码剖析》MonkeyRunner启动运行过程-小结

    老李推荐:第8章7节<MonkeyRunner源码剖析>MonkeyRunner启动运行过程-小结   poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化测试,性 ...

  9. 老李推荐:第8章5节《MonkeyRunner源码剖析》MonkeyRunner启动运行过程-运行测试脚本

    老李推荐:第8章5节<MonkeyRunner源码剖析>MonkeyRunner启动运行过程-运行测试脚本   poptest是国内唯一一家培养测试开发工程师的培训机构,以学员能胜任自动化 ...

随机推荐

  1. [selenium webdriver Java]处理弹出窗口

    Selenium WebDriver测试弹出窗口,包括识别弹出窗口,将driver转到新的窗口,在新的串钩中执行而是步骤,然后再转换到最初的窗口. 通过名称(name)识别和处理: Selenium ...

  2. mssql server 2005还原数据库bak文件与“备份集中的数据库备份与现有的xx数据库不同”解决方法

    mssql server 2005还原数据库bak文件,网站使用虚拟主机建站会经常遇到,一般情况下,主机商有在线的管理程序,但有时候没有的话,就需要本地还原备份sql数据库了.这种情况mssql se ...

  3. C#中克隆随机数的三种方法(为什么我想到了茴字的四种写法

    C#中的Random类可以用来产生伪随机数(正确的废话 伪随机数的一个性质就是给定一个初始种子,那么产生的随机数列都是相同的,这个性质非常适合用在不同环境之间同步逻辑的场景. 最近有一个要克隆当前随机 ...

  4. DOS命令关闭进程

    1.开始-运行,输入cmd后回车; 2.在DOS提示符下,先用命令 tasklist 回车来获取进程的 PID(例如获取了Explorer.EXE进程的PID为1988); 3.然后再输入命令:tas ...

  5. HW6.11

    import java.util.Scanner; public class Solution { public static void main(String[] args) { Scanner i ...

  6. 【noip模拟】考试总结

    今天睡了14个小时啊 把一星期的觉都补回来了 要不是被叫醒了 我肯定还在睡觉- - 其实现在还想睡... 集训真是伤身啊 感觉再睡就要睡成sb了 鉴于昨天被完虐(真·完虐 怒垫底) 来写篇总结 得分: ...

  7. IntelliJ远程调试教程

    概述 对于分布式系统的调试不知道大家有什么好的方法.对于我来说,在知道远程调试这个方法之前就是在代码中打各种log,然后重新部署,上线,调试,这样比较费时.今天咱们来了解了解Java远程调试这个牛逼的 ...

  8. SQL2008-表对表直接复制数据

    1.全部复制,使用简单,但是字段容易出错(字段和顺序必须相同)  INSERT INTO AAAStuffAgitationYield SELECT * FROM StuffAgitationYiel ...

  9. smarty3--registerPlugin()函数报错问题

    smarty版本:smarty3.1.30 registerPlugin错误信息: Notice: Trying to get property of non-object in E:\Joomla\ ...

  10. centos7 挂载ntfs移动硬盘

    第一步:下载安装rpmforge ,下载地址 http://pkgs.repoforge.org/rpmforge-release/  安装 rpm -ivh rpmforge-release-0.5 ...