Linux kmalloc/kfree 源码解读

kmalloc/kfree用于划分和回收内核空间低区内存的方法。改组方法没有直接通过伙伴系统进行内存的划分,通过slab算法进行分配的。同时也为每个CPU提供一个阵列缓存,用于提高分配效率。下面对改组函数进行源码级的分析。

内存分配

static inline void *kmalloc(size_t size, gfp_t flags)

1.         从Slab通用缓存中查找可用的缓存(可以分配的)

cachep = __find_general_cachep(size, flags);

if (unlikely(cachep == NULL))

return NULL;

如果没找到可用的缓存,直接返回0,表示分配失败。

2.         接着,就从缓存中分配Slab对象。先从CPU的阵列缓存中申请对象。如果缓存中还有Slab对象。

ac = cpu_cache_get(cachep);

if (likely(ac->avail)) {

STATS_INC_ALLOCHIT(cachep);

ac->touched = 1;

objp = ac->entry[--ac->avail];

}

3.         如果阵列缓存中没有对象,则需要向Slab缓存申请对象,重填阵列缓存,然后再分配对象。

a)         首先尝试从节点的共享缓存中进行分配。

if (l3->shared) {

struct array_cache *shared_array = l3->shared;

if (shared_array->avail) {

if (batchcount > shared_array->avail)

batchcount = shared_array->avail;

shared_array->avail -= batchcount;

ac->avail = batchcount;

memcpy(ac->entry,

&(shared_array->entry[shared_array->avail]),

sizeof(void *) * batchcount);

shared_array->touched = 1;

// 分配成功

goto alloc_done;

}

}

b)        接着判断Slab缓存是不是空了,如果空了就需要为缓存注入新的血液。我们知道Slab缓存中有3个链表,分别指向全满,半满和全空的Slab。通过判断这三个链表是不是为空,来决定要不要向伙伴系统申请Slab缓存。

entry = l3->slabs_partial.next;

if (entry == &l3->slabs_partial) {

l3->free_touched = 1;

entry = l3->slabs_free.next;

if (entry == &l3->slabs_free)

goto must_grow;

}

c)        如果缓存中仍然存在可用的Slab对象,则分配,填充阵列缓存。

while (slabp->inuse < cachep->num && batchcount--) {

ac->entry[ac->avail++] = slab_get_obj(cachep, slabp,

numa_node_id());

}

d)        如果发现Slab缓存中的对象都已经分配完了,需要从伙伴系统中申请Slab对象,来增长缓存。

if (unlikely(!ac->avail)) {

int x;

x = cache_grow(cachep, flags, numa_node_id());

// cache_grow can reenable interrupts, then ac could change.

ac = cpu_cache_get(cachep);

if (!x && ac->avail == 0)      // no objects in sight? abort

return NULL;

if (!ac->avail)  // objects refilled by interrupt?

goto retry;

}

kfree函数很简单,将Slab对象释放到阵列缓存中,如果缓存满了,则批量释放到Slab缓存中

时间: 2024-12-28 13:47:00

Linux kmalloc/kfree 源码解读的相关文章

HttpClient 4.3连接池参数配置及源码解读

目前所在公司使用HttpClient 4.3.3版本发送Rest请求,调用接口.最近出现了调用查询接口服务慢的生产问题,在排查整个调用链可能存在的问题时(从客户端发起Http请求->ESB->服务端处理请求,查询数据并返回),发现原本的HttpClient连接池中的一些参数配置可能存在问题,如defaultMaxPerRoute.一些timeout时间的设置等,虽不能确定是由于此连接池导致接口查询慢,但确实存在可优化的地方,故花时间做一些研究.本文主要涉及HttpClient连接池.请求的参数

基于Docker的TensorFlow机器学习框架搭建和实例源码解读

概述:基于Docker的TensorFlow机器学习框架搭建和实例源码解读,TensorFlow作为最火热的机器学习框架之一,Docker是的容器,可以很好的结合起来,为机器学习或者科研人员提供便捷的机器学习开发环境,探索人工智能的奥秘,容器随开随用方便快捷.源码解析TensorFlow容器创建和示例程序运行,为热爱机器学者降低学习难度. 默认机器已经装好了Docker(Docker安装和使用可以看我另一篇博文:Ubuntu16.04安装Docker1.12+开发实例+hello world+w

精通Spark:Spark内核剖析、源码解读、性能优化和商业案例实战

这是世界上第一个Spark内核高端课程: 1, 该课程在对Spark的13个不同版本源码彻底研究基础之上提炼而成: 2, 课程涵盖Spark所有内核精髓的剖析: 3, 课程中有大量的核心源码解读: 4, 全景展示Spark商业案例下规划.部署.开发.管理技术: 5, 涵盖Spark核心优化技巧 该课程是Spark的高端课程,其前置课程是“18小时内掌握Spark:把云计算大数据速度提高100倍以上!”. 培训对象 1,  系统架构师.系统分析师.高级程序员.资深开发人员: 2, 牵涉到大数据处理

(转)go语言nsq源码解读二 nsqlookupd、nsqd与nsqadmin

转自:http://www.baiyuxiong.com/?p=886 ----------------------------------------------------------------------- 上一篇go语言nsq源码解读-基本介绍  介绍了最基本的nsq环境搭建及使用.在最后使用时,我们用到了几个命令:nsqlookupd.nsqd.nsqadmin.curl及 nsq_to_file,并看到用curl命令写入的几个”hello world”被nsq_to_file命令保

自动化WiFI钓鱼工具——WiFiPhisher源码解读

工具介绍 开源无线安全工具Wifiphisher是基于MIT许可模式的开源软件,运行于Kali Linux之上. github.com/sophron/wifiphisher 它能够对WPA加密的AP无线热点实施自动化钓鱼攻击,获取密码账户.由于利用了社工原理实施中间人攻击,Wifiphisher在实施攻击时无需进行暴力破解. 此外安利一个我们正在开发的项目,基于wifiphisher的校园网钓鱼工具,希望有小伙伴来一起玩耍:-P github.com/noScripts/Campus-Fake

Spring源码解读之核心容器上节

Spring架构图 说明 Spring的流行程度就不用我来说了,相信大家如果使用JAVA开发就一定知道它.写这篇文章的初衷在于:1.了解Spring底层实现原理,提升对Spring的认识与理解.2.学习优秀框架编程实现,学习优秀的设计模式.3.使用Spring三年多,对于底层细节希望知道更多,便于求职. 对于Spring整个架构是很庞大的,很难一下看完和思考完,所以我会从Core Container进行切入,一步一步往上走,从而解开Spring神秘的底层面纱.同时对Spring的IOC\AOP\

QCustomplot使用分享(二) 源码解读

一.头文件概述 从这篇文章开始,我们将正式的进入到QCustomPlot的实践学习中来,首先我们先来学习下QCustomPlot的类图,如果下载了QCustomPlot源码的同学可以自己去QCustomPlot的目录下documentation/qcustomplot下寻找一个名字叫做index.html的文件,将其在浏览器中打开,也是可以找到这个库的类图.如图1所示,是组成一个QCustomPlot类图的可能组成形式. 一个图表(QCustomPlot):包含一个或者多个图层.一个或多个ite

vue源码解读预热-0

vueJS的源码解读 vue源码总共包含约一万行代码量(包括注释)特别感谢作者Evan You开放的源代码,访问地址为Github 代码整体介绍与函数介绍预览 代码模块分析 代码整体思路 总体的分析 从图片中可以看出的为采用IIFE(Immediately-Invoked Function Expression)立即执行的函数表达式的形式进行的代码的编写 常见的几种插件方式: (function(,){}(,))或(function(,){})(,)或!function(){}()等等,其中必有

SpringMVC源码解读 - RequestMapping注解实现解读 - RequestCondition体系

一般我们开发时,使用最多的还是@RequestMapping注解方式. @RequestMapping(value = "/", param = "role=guest", consumes = "!application/json") public void myHtmlService() { // ... } 台前的是RequestMapping ,正经干活的却是RequestCondition,根据配置的不同条件匹配request. @Re