诸暨网站制作设计网站做缓存吗

diannao/2026/1/17 21:27:59/文章来源:
诸暨网站制作设计,网站做缓存吗,品牌策划方案怎么写,广州网络安全建设公司提起buddy system相信很多人不会陌生#xff0c;它是一种经典的内存分配算法#xff0c;大名鼎鼎的Linux底层的内存管理用的就是它。这里不探讨内核这么复杂实现#xff0c;而仅仅是将该算法抽象提取出来#xff0c;同时给出一份及其简洁的源码实现#xff0c;以便定制扩展…提起buddy system相信很多人不会陌生它是一种经典的内存分配算法大名鼎鼎的Linux底层的内存管理用的就是它。这里不探讨内核这么复杂实现而仅仅是将该算法抽象提取出来同时给出一份及其简洁的源码实现以便定制扩展。 伙伴分配的实质就是一种特殊的“分离适配”即将内存按2的幂进行划分相当于分离出若干个块大小一致的空闲链 表搜索该链表并给出同需求最佳匹配的大小。其优点是快速搜索合并O(logN)时间复杂度以及低外部碎片最佳适配best-fit其缺点是内 部碎片因为按2的幂划分块如果碰上66单位大小那么必须划分128单位大小的块。但若需求本身就按2的幂分配比如可以先分配若干个内存池在其基 础上进一步细分就很有吸引力了。 可以在维基百科上找到该算法的描述大体如是 分配内存 1.寻找大小合适的内存块大于等于所需大小并且最接近2的幂比如需要27实际分配32 .如果找到了分配给应用程序。如果没找到分出合适的内存块。.对半分离出高于所需大小的空闲内存块.如果分到最低限度分配这个大小。回溯到步骤1寻找合适大小的块.重复该步骤直到一个合适的块  释放内存 1.释放该内存块 寻找相邻的块看其是否释放了。如果相邻块也释放了合并这两个块重复上述步骤直到遇上未释放的相邻块或者达到最高上限即所有内存都释放了。上面这段文字对你来说可能看起来很费劲没事我们看个内存分配和释放的示意图你就知道了 上图中首先我们假设我们一个内存块有1024K当我们需要给A分配70K内存的时候 我们发现1024K的一半大于70K然后我们就把1024K的内存分成两半一半512K。然后我们发现512K的一半仍然大于70K于是我们再把512K的内存再分成两半一半是128K。此时我们发现128K的一半小于70K于是我们就分配为A分配128K的内存。后面的BCD都这样而释放内存时则会把相邻的块一步一步地合并起来合并也必需按分裂的逆操作进行合并。 我们可以看见这样的算法用二叉树这个数据结构来实现再合适不过了。 我在网上分别找到cloudwu和wuwenbin写的两份开源实现和测试用例。实际上后一份是对前一份的精简和优化本文打算从后一份入手讲解因为这份实现真正体现了“极简”二字追求突破常规的极致简单的设计。网友对其评价甚高甚至可用作教科书标准实现看完之后回过头来看cloudwu的代码就容易理解了。 分配器的整体思想是通过一个数组形式的完全二叉树来监控管理内存二叉树的节点用于标记相应内存块的使用状态高层节点对应大的块低层节点对应 小的块在分配和释放中我们就通过这些节点的标记属性来进行块的分离合并。如图所示假设总大小为16单位的内存我们就建立一个深度为5的满二叉树根 节点从数组下标[0]开始监控大小16的块它的左右孩子节点下标[1~2]监控大小8的块第三层节点下标[3~6]监控大小4的块……依此类推。 在分配阶段首先要搜索大小适配的块假设第一次分配3转换成2的幂是4我们先要对整个内存进行对半切割从16切割到4需要两步那么从下标 [0]节点开始深度搜索到下标[3]的节点并将其标记为已分配。第二次再分配3那么就标记下标[4]的节点。第三次分配6即大小为8那么搜索下标 [2]的节点因为下标[1]所对应的块被下标[3~4]占用了。 在释放阶段我们依次释放上述第一次和第二次分配的块即先释放[3]再释放[4]当释放下标[4]节点后我们发现之前释放的[3]是相邻的 于是我们立马将这两个节点进行合并这样一来下次分配大小8的时候我们就可以搜索到下标[1]适配了。若进一步释放下标[2]同[1]合并后整个内存 就回归到初始状态。 还是看一下源码实现吧首先是伙伴分配器的数据结构 struct buddy2 {   unsigned size;   unsigned longest[1]; }; 这里的成员size表明管理内存的总单元数目测试用例中是32成员longest就是二叉树的节点标记表明所对应的内存块的空闲单位在下文中会分析这是整个算法中最精妙的设计。此处数组大小为1表明这是可以向后扩展的注在GCC环境下你可以写成longest[0]不占用空间这里是出于可移植性考虑我们在分配器初始化的buddy2_new可以看到这种用法。 truct buddy2* buddy2_new( int size ) {   struct buddy2* self;   unsigned node_size;   int i;     if (size  1 || !IS_POWER_OF_2(size))     return NULL;     self  (struct buddy2*)ALLOC( 2 * size * sizeof(unsigned));   self-size  size;   node_size  size * 2;     for (i  0; i  2 * size - 1; i) {     if (IS_POWER_OF_2(i1))       node_size / 2;     self-longest[i]  node_size;   }   return self; } 整个分配器的大小就是满二叉树节点数目即所需管理内存单元数目的2倍。一个节点对应4个字节longest记录了节点所对应的的内存块大小。 内存分配的alloc中入参是分配器指针和需要分配的大小返回值是内存块索引。alloc函数首先将size调整到2的幂大小并检查是否超过最大限度。然后进行适配搜索深度优先遍历当找到对应节点后将其longest标记为0即分离适配的块出来并转换为内存块索引offset返回依据二叉树排列序号比如内存总体大小32我们找到节点下标[8]内存块对应大小是4则offset (81)*4-32 4那么分配内存块就从索引4开始往后4个单位。 int buddy2_alloc(struct buddy2* self, int size) {   unsigned index  0;   unsigned node_size;   unsigned offset  0;     if (selfNULL)     return -1;     if (size  0)     size  1;   else if (!IS_POWER_OF_2(size))     size  fixsize(size);     if (self-longest[index]  size)     return -1;     for(node_size  self-size; node_size ! size; node_size / 2 ) {     if (self-longest[LEFT_LEAF(index)]  size)       index  LEFT_LEAF(index);     else       index  RIGHT_LEAF(index);   }     self-longest[index]  0;   offset  (index  1) * node_size - self-size;     while (index) {     index  PARENT(index);     self-longest[index]        MAX(self-longest[LEFT_LEAF(index)], self-longest[RIGHT_LEAF(index)]);   }     return offset; } 在函数返回之前需要回溯因为小块内存被占用大块就不能分配了比如下标[8]标记为0分离出来那么其父节点下标[0]、[1]、[3]也需要相应大小的分离。将它们的longest进行折扣计算取左右子树较大值下标[3]取4下标[1]取8下标[0]取16表明其对应的最大空闲值。 在内存释放的free接口我们只要传入之前分配的内存地址索引并确保它是有效值。之后就跟alloc做反向回溯从最后的节点开始一直往上找到longest为0的节点即当初分配块所适配的大小和位置。我们将longest恢复到原来满状态的值。继续向上回溯检查是否存在合并的块依据就是左右子树longest的值相加是否等于原空闲块满状态的大小如果能够合并就将父节点longest标记为相加的和多么简单。 void buddy2_free(struct buddy2* self, int offset) {   unsigned node_size, index  0;   unsigned left_longest, right_longest;     assert(self  offset  0  offset  size);     node_size  1;   index  offset  self-size - 1;     for (; self-longest[index] ; index  PARENT(index)) {     node_size * 2;     if (index  0)       return;   }     self-longest[index]  node_size;     while (index) {     index  PARENT(index);     node_size * 2;       left_longest  self-longest[LEFT_LEAF(index)];     right_longest  self-longest[RIGHT_LEAF(index)];       if (left_longest  right_longest  node_size)       self-longest[index]  node_size;     else       self-longest[index]  MAX(left_longest, right_longest);   } } 上面两个成对alloc/free接口的时间复杂度都是O(logN)保证了程序运行性能。然而这段程序设计的独特之处就在于使用加权来标记内存空闲状态而不是一般的有限状态机实际上longest既可以表示权重又可以表示状态状态机就毫无必要了所谓“少即是多”嘛反 观cloudwu的实现将节点标记为UNUSED/USED/SPLIT/FULL四个状态机反而会带来额外的条件判断和管理实现而且还不如数值那 样精确。从逻辑流程上看wuwenbin的实现简洁明了如同教科书一般特别是左右子树的走向内存块的分离合并块索引到节点下标的转换都是一步到 位不像cloudwu充斥了大量二叉树的深度和长度的间接计算让代码变得晦涩难读这些都是longest的功劳。一个“极简”的设计往往在于你想不到的突破常规思维的地方。 这份代码唯一的缺陷就是longest的大小是4字节内存消耗大。但cloudwu的博客上有人提议用logN来保存值这样就能实现uint8_t大小了看又是一个“极简”的设计 说实话很难在网上找到比这更简约更优雅的buddy system实现了——至少在Google上如此。 原文链接 译文链接转载于:https://www.cnblogs.com/rinack/p/3368352.html

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/diannao/90936.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

企业网站建站系统哪个好用天津优化网络公司的建议

一、项目简介 本项目是一套基于springbootvue实现的高校宿舍管理系统设计与实现 包含:项目源码、数据库脚本等,该项目附带全部源码可作为毕设使用。 项目都经过严格调试,eclipse或者idea 确保可以运行! 该系统功能完善、界面美观…

怎么创造免费网站搜索引擎付费推广

此为牛客网Linux C课程 1.4&1.5 的课程笔记。 0. 关于静态库与动态库 库就是封装好的、可服用的代码,而静态和动态是指链接。 这节课讲的是静态库,是指在链接阶段,会将汇编生成的目标文件.o与引用到的库一起链接打包到可执行文件中&…

做游戏钓鱼网站浮动微信代码wordpress

法国时间6月19日,OPPO在巴黎卢浮宫正式举办未来旗舰Find X发布会。此次亮相的Find X新机,既有充满艺术感的3D玻璃机身设计,又有3D结构光、曲面全景屏、双轨潜望结构等多项黑科技。众多黑科技中,以3D结构光O-face最受数目。据悉&am…

网站设计毕业设计题目专业seo关键词优化

一、什么是大端和小端 所谓的大端模式,就是高位字节排放在内存的低地址端,低位字节排放在内存的高地址端。 所谓的小端模式,就是低位字节排放在内存的低地址端,高位字节排放在内存的高地址端。 简单来说:大端——高尾端,小端——低尾端 举个例子,比如数字 0x12 34 56 78…

跳转网站代码300网站建设

当使用术语“生命周期”时,Spring的家伙指的是您的bean的构造和破坏,通常这与Spring Context的构造和破坏有关。 在某些情况下,Bean生命周期的管理不是一件容易的事,因为需要它执行自己的内部设置。 当您的bean必须与外部系统进行…

男生女生在床上做的那个网站保定网站维护公司

不可以; 不能直接从一个静态方法内部调用非静态方法。 这是因为静态方法是属于类的,而非静态方法是属于类的实例的。 静态方法可以在没有创建类的实例的情况下被调用,而非静态方法需要通过类的实例来调用。 如果想要从静态方法内部调用非…

seo 最新北京谷歌seo

1.通过 URL 传参 在页面跳转时,可以在 URL 中携带参数进行传递,然后在目标页面的 onLoad 生命周期中获取参数。 // 在页面 A 中跳转到页面 B 并传递参数 wx.navigateTo({url: /pages/detail/index?id123 });// 在页面 B 的 onLoad 生命周期中获取参数…

申报网站天津小型网站建设

教育 -团队管理-章节资料考试资料-无锡商业职业技术学院【】 模块1 团队起源与发展随堂测验 1、【单选题】团队应该有一个既定的(),为团队成员导航,知道要向何处去,没有()这个团队就没有存在的价…

网站制作加教程视频教程一份完整app运营推广方案

今年专业课811信号与系统139分,总分400,顺利上岸南昌大学,回首这一年的复习,有很多经验想和大家分享,希望对大家复习会有一些帮助。专业课:139分,811信号与系统 主要参考书:《信号与…

凡科做的网站百度不到制作我的第一个网页

文章目录 mock 测试unittest.mockMock类MagicMock类patch装饰器create_autospec函数断言的方法 pytest-mock 使用 mock 测试 在单元测试时,有些数据需要依赖其他服务或者不好获取到,此时需要使用mock来模拟对应的函数、对象等。 mock模拟数据的python…

2020站群seo系统wordpress ftp 设置

系统功能: 基于STM8的便携式智能药盒控制系统设计的总体方案设计,目前确定的模块主要有: STM8、蓝牙模块、时钟芯片、时钟和复位电路、压力传感器、声光报警电路、按键模块、系统电源模块构成。 STM8:核心控制器,完成各模块的控…

预告网站正在建设中乱码网站怎么办

【2023】Jenkins入门与安装_jenkins最新版本_丶重明的博客-CSDN博客 也可以结合这个互补看 前言 你平常在做自己的项目时,是否有过部署项目太麻烦的想法?如果你是单体项目,可能没什么感触,但如果你是微服务项目,相…

网站没权重王烨明

高刷屏和手机使用时长本质上并没有什么关系,但是购买高刷屏的手机却可以让你得到更好的体验,而且高刷屏绝对是未来手机行业发展的一个主流方向,所以说目前如果有新机购买的计划的话,配备高刷屏的手机是一个很好的选择。不过数码君…

企业网站首页设计评价科技网站设计

简述 CloudCanal 最近再次对其 Oracle 源端数据同步进行了一系列优化,这些优化基于用户在真实场景中的反馈,具备很强的生产级别参考意义。 本文将简要介绍这些优化项,希望带给读者一些收获。 增量事件 SCN 乱序问题MISSING_SCN 事件干扰新…

网页设计模板网站推荐国外免费源码共享网站

学习目标: 掌握解决Edge浏览器常见问题的方法。提升对浏览器故障排除的能力。 学习内容: 常见Edge浏览器问题的识别和解决方法。例如页面加载慢、无法访问特定网站、崩溃或无响应等。更新Edge浏览器和操作系统,以确保拥有最新的安全补丁和功…

一个网站绑定两个域名wordpress开始安装

推荐阅读100套最新项目 最新ssmjava项目文档视频演示可运行源码分享 最新jspjava项目文档视频演示可运行源码分享 最新Spring Boot项目文档视频演示可运行源码分享 目录 前台功能效果图 管理员功能登录前台功能效果图 系统功能设计 数据库E-R图设计 lunwen参考 摘要 研究…

门户网站cms网站幻灯通栏代码

文章目录1. 概述2. 数据3. 模型4. 训练5. 测试参考 基于深度学习的自然语言处理本文使用attention机制的模型,将各种格式的日期转化成标准格式的日期 1. 概述 LSTM、GRU 减少了梯度消失的问题,但是对于复杂依赖结构的长句子,梯度消失仍然存…

广汉市建设局网站赣榆区城乡建设局网站

1. 引言 对于ASP.NET Core应用程序来说,我们要记住非常重要的一点是:其本质上是一个独立的控制台应用,它并不是必需在IIS内部托管且并不需要IIS来启动运行(而这正是ASP.NET Core跨平台的基石)。ASP.NET Core应用程序拥…

唐山网站托管四川网站建设贴吧

Tip: 如果你在进行深度学习、自动驾驶、模型推理、微调或AI绘画出图等任务,并且需要GPU资源,可以考虑使用Compshare的GPU算力云平台。他们提供高性价比的4090 GPU,按时收费每卡2.6元,月卡只需要1.7元每小时,并附带200G…