内存池的面试整理
文章思路来源
- 如何实现无锁申请?
- 每个线程申请自己的TreadCacheTLS对象,来管理自己的freeList数组。
- 小内存的大小?
- 0-256K,并且对申请到的内存进行字节对齐,保证申请到的内存可以映射到对应的freeList中。
- 映射规则?
- 从128字节开始每个区间8倍递增,从16(8到16是两倍)字节开始对齐每8倍递增,到256KB,8K对齐结束。每个区间为16,56,56,56,24,共208个freeList
- 为什么从8字节开始对齐?让freeList保存下一个节点的地址,即使在64位系统下
- freeList如何管理内存?
- 将申请到的内存块头插到对应的freeList,每次需要内存就头删一个内存块。
- 如何向centralCache申请内存?
- 首先利用相同的哈希值来得到对应的spanList,获取到一个span,里面存储的是切好size大小的freeList,并且物理空间是连续的。然后返回ThreadCache需要的内存块数。
- 如何连续?
- 将申请到的未切分span,进行尾插
- 如何向pageCache申请内存?
- 首先将centralCache申请的页数(不足一页申请一页),映射到对应的spanList上,取出一个span,并记录span内每个页号和span的映射关系后,返回给centralCache。
- 为空则向spanList后遍历,如果找到一个span,则再创建一个span,一个span存所需的页,返回给centralCache,一个span存剩余的页,并将这个span挂到对应spanList内。
- 都为空,则向系统申请一个128页的大span,重新进行前面的流程。
创建两个span,一个span返回,一个span挂到对应spanList内。
- 为什么双向链表?
- 方便回收span时,找到前一个节点
- 项目中有使用new吗
- 新建了一个定长内存池,每次需要对象时从这里面申请,并且用的是定位new,直接再给定地址内开辟空间
- 内存池只分配内存给对象,至于内存如何使用就看对象如何使用比如将void*转换为int*然后修改指向的空间
- 什么时候加锁?
- centralCache从span中返回内存块时加锁(删除)
- centralCache将pageCache中的span挂到spanList时加锁(增加)
- centralCache合并内存块到span需要加锁(合并)
- PageCache寻找可用span时需要加锁(删除)
- PageCache合并span时需要加锁(合并)
- 一般涉及到对数据的增删改操作时,需要加锁
- 如何释放内存?
- ThreadCache释放指向内存空间的指针时,会根据指针地址找到页号然后找到对应的span,进而知道内存块大小,就能找到归还的freeList,当归还的内存块等于批量申请的内存块数量后,就可以归还这个freeList给span
- 调用centralCache函数,找到该freeList的所属的spanList,加锁后,根据页号和span的关系,将freeList归还给spanList内的span,解锁后
- 调用PageCache函数,PageCache同样利用页号和span的关系进行向前向后合并,将合并后的span挂到对应spanList内,并在spanList内删掉合并用掉的span
- 页号和地址的可以互相转换,只需要将地址除8K得到页号,因为每个地址都是以8K递增,相应的页号+1
- 向前向后合并的条件是,span不为空且没有被使用
- 大内存如何申请?
- 计算对齐后需要的页数,然后PageCache向系统申请空间,建立页号和span的映射后返回该span,利用span的页号左移13位得到指针地址并返回。释放该内存,则直接释放给系统,而不是还给内存池。
- 链表的头节点,如何连接?
- 头几个字节,并且为了适配不同平台,将一级指针强转为二级指针再取其地址。
- 改进的点?
- 使用RAII机制管理锁
- 加入日志线程
- freeList,spanList
- freeList记录申请内存块数,批量申请的数量
- spanList记录span的头节点
- span记录页号、页数、前后指针、切好的size大小、使用掉的内存块数、是否在使用
- 慢开始机制
- 申请块数以1递增,直到当前申请的内存块数大于最大可申请数
- 亮点/细节:
- 慢开始机制
- 基数树
- 为了保证连续,进行尾插
- 使用定长内存池模板,每次创建list的头节点都从里面申请
- ConcurrentAlloc:首先,当线程需要size个字节时,会从定长内存池中先加锁创建tls线程缓存对象,
- Allocate:将size进行字节对齐,并计算key找到对应的freeList,从该freeList中无锁的获取头部的内存块(哈希桶用每个定长内存块的头部来作为链表下一个节点的地址)
(哈希桶的映射规则是
0-128,以8字节对齐,分为0-15,
129-1K,以16字节对齐,分为16-71,
1K+1-8K,以128字节对齐,分为72-127,
8K+1-64K,以1024字节对齐,分为128-183,
64K+1-256K,以8K对齐,分为184-207) - FetchFromCentralCache:如果对应freeList为空,则向中间缓存利用慢开始机制申请一定数量的内存块,
- FetchRangeObj:首先中间缓存根据相同的key来找对应的spanList,内部存储切好size大小的freeList(每个span(大小为8K)内包含一定数量的size内存块,)然后加锁从桶内的一个span获取(头删)需要的内存块数,线程缓存得到中间缓存分配的内存块后,将第一个内存块分给线程,将剩余的内存块头插到freeList里。
- GetOneSpan:如果中间缓存的当前span哈希桶为空,首先把中间缓存锁解锁用以防止其他线程释放内存时需要等待,然后加上页锁,向页缓存申请空间,
- NewSpan:页缓存保存的是管理页的spanList,它的映射规则是直接定址法,每个key保存的都是key个页的span。
- 中间缓存需要申请k个页时映射到对应spanList上,取出一个span,建立页号和span的映射,返回给中间缓存,
- 如果对应spanList没有span,就遍历k之后的spanList,有则切分k个,并将剩余的span头插到对应的spanList上,建立页号和span的映射,返回这个span。
- 如果k之后的spanList都为空,则从定长内存池新建一个span对象,为其分配128页连续的内存空间,然后重新切分k,头插剩余的span到对应spanList内+映射,返回这个span。
- GetOneSpan:中间缓存拿到span后解锁页缓存锁,将span划分为size大小的内存块,保持物理空间连续,将切好的span加锁后头插到对应spanList内,从span内获取n个对象返回给线程缓存,线程缓存在返回一个对象给线程,并把剩下的对象头插到对应freeList内。
释放内存:
MapObjectToSpan:计算指针地址到span的映射,获取内存块的大小
Deallocate:根据内存块的大小归还到相应freeList内,当其内的内存块数量大于分配的数量后,
分配的数量有慢开始机制计算,每次申请就递加一个,(机制)
ListTooLong:就把这些归还给centralCache
ReleaseListToSpans:根据相同的key找到spanList后,加锁后,根据映射关系将内存块归还给span里的freeList,直到所有内存块归还完毕后就将这个span归还给pageCache,解锁
ReleaseSpanToPageCache:加锁,首先看
- 向前能否合并,根据前一个span的页号找到前一个span判断是否为空,是否正在被使用,是则无法合并
- 然后向前合并页号以及页数,并把前一个span对应的spanList删除,并且回收前一个span的空间
- 循环上述判断直到退出
- 向后能否合并,根据后一个span的页号(span+页数=后一个)找到对应span,进行向后合并,直到不满足后一个span不为空,未使用。
- 将合并后的span挂到指定位置,并建立页号和span的映射关系(重复则覆盖)
- 解锁
相关文章:
内存池的面试整理
文章思路来源 如何实现无锁申请? 每个线程申请自己的TreadCacheTLS对象,来管理自己的freeList数组。小内存的大小? 0-256K,并且对申请到的内存进行字节对齐,保证申请到的内存可以映射到对应的freeList中。映射规则&am…...
优化记录 -- 记一次搜索引擎(SOLR)优化
业务场景 某服务根据用户相关信息,使用搜索引擎进行数据检索 软件配置 solr 1台:32c 64g 数据10gb左右,版本 7.5.5 应用服务器1台:16c 64g 应用程序 3节点 问题产生现象 1、因业务系统因处理能不足,对业务系统硬件…...
电力感知边缘计算网关产品设计方案-网关系统通信架构方案
1.边缘协同控制模发 能针对建筑、充电桩、分布式储能、分布式光伏等典型设备建立对应物模型、完成数据采集通信协议设计和控制指令交互设计,能针对建筑、充换电站等典型场景提出具体实施方案和人工智能控制算法和逻辑。物模型、通信协议设计和控制指令交互设计科学、先进,能…...
RabbitMQ消息的可靠性
RabbitMQ消息的可靠性 一 生产者的可靠性 生产者重试 有时候由于网络问题,会出现连接MQ失败的情况,可以配置重连机制 注意:SpringAMQP的重试机制是阻塞式的,重试等待的时候,当前线程会等待。 spring:rabbitmq:conne…...
Opengl 纹理(知识点)
纹理(知识点) 以下是纹理用到的知识点,至于具体流程操作请参考: https://learnopengl.com/Getting-started/Textures 纹理环绕 纹理环绕(Texture Wrapping)的作用是定义在纹理坐标超出标准范围时系统如何…...
Centos 7 安装yum(针对python卸载yum出错)
提前下载所需安装包,按照下面顺序安装即可完成,每个依赖包必须正确安装 下载地址:http://mirrors.163.com/centos/7/os/x86_64/Packages/ rpm -qa|grep python|xargs rpm -ev --allmatches --nodeps ##强制删除已安装程序及其关联 whereis …...
substr()与substring()的区别
在 JavaScript 编程语言中,substr() 和 substring() 都是字符串函数,用于截取指定位置的子字符串。虽然这两个函数都可以用于截取字符串,但它们之间存在一些区别。 substr() 语法:string.substr(start,length) 参数值:…...
MacOS 成为恶意软件活动的目标
Malwarebytes 警告称,一个针对 Mac 操作系统 (OS) 的数据窃取程序正在通过虚假的网络浏览器更新分发给毫无戒心的目标。 Atomic Stealer,也称为 AMOS,是 Mac OS 上流行的窃取程序。 Atomic Stealer (AMOS) 恶意软件最近被发现使用“ClearFa…...
从0开始学习JavaScript--JavaScript生成器
JavaScript生成器(Generator)是一项强大的语言特性,它允许函数在执行过程中被暂停和恢复,从而实现更灵活的控制流。本文将深入探讨JavaScript生成器的基本概念、用法,并通过丰富的示例代码展示其在实际应用中的优势和强…...
householder进行矩阵QR分解
文章目录 1. Householder 进行QR分解 1. Householder 进行QR分解 A Q R (1) AQR\tag1 AQR(1) A [ 1 2 0 1 1 0 3 1 1 0 3 2 1 2 0 2 ] (2) A\begin{bmatrix}1&2&0&1\\\\1&0&3&1\\\\1&0&3&2\\\\1&2&0&2\end{bmatrix}\tag2 A…...
利用叉积计算向量的旋向及折线段的拐向
一、向量叉积 两个向量 u u u、 v v v的叉积写作 u v n ∥ u ∥ ∥ v ∥ s i n θ \mathbf{u \times v n \left \| u \right \| \left \| v \right \| sin\theta } uvn∥u∥∥v∥sinθ 式中, n n n: 与 u u u、 v v v均垂直的单位向量,theta是两向量…...
Vmware 扩展硬盘空间后的操作-Ubuntu
在VMware中扩展了Ubuntu虚拟机的硬盘容量后,你需要在Ubuntu内部进行操作才能使用新增的空间。过程包括为增加的空间建立分区、格式化以及挂载该分区供使用。下面是具体的步骤: 首先登录到你的Ubuntu系统,用lsblk命令查看分区情况。这样你可以…...
Rust错误处理:Result
文章目录 简介错误匹配 Rust基础教程: 初步⚙ 所有权⚙ 结构体和枚举类⚙ 函数进阶⚙ 泛型和特征⚙ 并发和线程通信⚙ cargo包管理⚙ 可空类型Option Rust进阶教程: 用宏实现参数可变的函数⚙ 类函数宏 简介 Rust中没有提供类似try…catch之类…...
1410.HTML 实体解析器
题目来源: leetcode题目,网址:1410. HTML 实体解析器 - 力扣(LeetCode) 解题思路: 使用map存放特殊字符串及其应被替换为的字符串。然后遍历字符串替换 map 中的字符串即可。 解题代码: …...
Python通过串口收发文件
单位内外网是隔离的,USB对拷线被禁用,安全优盘使用太费事,就想到了通过串口传输文件. import serial from xmodem import XMODEM import osdef Send_File(filepath, portCOM8, baudrate115200):bn os.path.basename(filepath)filesize os.stat(filepath).st_sizestrSendFile…...
[crash] cxa_pure_virtual 崩溃分析与原理
摘要:工作过程中处理线上的崩溃时发现了一例cxa_pure_virtual相关的crash,直接看堆栈基本山很容易确认是有异步调用导致出发了ABI的异常。但是对于为什么会触发cxa_pure_virtual虽然有大致的猜测但是没有直接的证据,因此本文主要描述触发该类…...
2023年学习Go语言是否值得?探索Go语言的魅力
关注公众号【爱发白日梦的后端】分享技术干货、读书笔记、开源项目、实战经验、高效开发工具等,您的关注将是我的更新动力! 作为一门流行且不断增长的编程语言,Go语言在2023年是否值得学习呢?让我们来看看学习Go语言的好处以及为何…...
【C++11】=default与=delete关键字使用详解
系列文章目录 C11新特性使用详解-持续更新 文章目录 系列文章目录一、default关键字1. 为什么要引入default关键字2. 注意事项3. 使用default关键字有什么好处4.实例代码 二、delete关键字1. 为什么要引入delete关键字2. 注意事项3. 使用场景3.1删除默认构造函数3.2 删除拷贝构…...
[开源]Web端的P2P文件传输工具,简单安全高效的P2P文件传输服务
一、开源项目简介 小鹿快传 - 在线P2P文件传输工具 小鹿快传是一款Web端的P2P文件传输工具,使用了WebRTC技术实现P2P连接和文件传输。 二、开源协议 使用MIT开源协议 三、界面展示 产品截图 四、功能概述 简单安全高效的P2P文件传输服务 小鹿快传是一款Web端…...
边缘计算多角色智能计量插座 x 资产显示标签:实现资产追踪与能耗管理的无缝结合
越来越多智慧园区、智慧工厂、智慧医院、智慧商业、智慧仓储物流等企业商家对精细化、多元化智能生态应用场景的提升,顺应国家节能减排、环保的时代潮流,设计一款基于融合以太网/WiFi/蓝牙智能控制的智能多角色插座应运而生,赋予智能插座以遥…...
网络六边形受到攻击
大家读完觉得有帮助记得关注和点赞!!! 抽象 现代智能交通系统 (ITS) 的一个关键要求是能够以安全、可靠和匿名的方式从互联车辆和移动设备收集地理参考数据。Nexagon 协议建立在 IETF 定位器/ID 分离协议 (…...
谷歌浏览器插件
项目中有时候会用到插件 sync-cookie-extension1.0.0:开发环境同步测试 cookie 至 localhost,便于本地请求服务携带 cookie 参考地址:https://juejin.cn/post/7139354571712757767 里面有源码下载下来,加在到扩展即可使用FeHelp…...
Java 语言特性(面试系列1)
一、面向对象编程 1. 封装(Encapsulation) 定义:将数据(属性)和操作数据的方法绑定在一起,通过访问控制符(private、protected、public)隐藏内部实现细节。示例: public …...
css实现圆环展示百分比,根据值动态展示所占比例
代码如下 <view class""><view class"circle-chart"><view v-if"!!num" class"pie-item" :style"{background: conic-gradient(var(--one-color) 0%,#E9E6F1 ${num}%),}"></view><view v-else …...
mongodb源码分析session执行handleRequest命令find过程
mongo/transport/service_state_machine.cpp已经分析startSession创建ASIOSession过程,并且验证connection是否超过限制ASIOSession和connection是循环接受客户端命令,把数据流转换成Message,状态转变流程是:State::Created 》 St…...
在鸿蒙HarmonyOS 5中使用DevEco Studio实现录音机应用
1. 项目配置与权限设置 1.1 配置module.json5 {"module": {"requestPermissions": [{"name": "ohos.permission.MICROPHONE","reason": "录音需要麦克风权限"},{"name": "ohos.permission.WRITE…...
Java多线程实现之Thread类深度解析
Java多线程实现之Thread类深度解析 一、多线程基础概念1.1 什么是线程1.2 多线程的优势1.3 Java多线程模型 二、Thread类的基本结构与构造函数2.1 Thread类的继承关系2.2 构造函数 三、创建和启动线程3.1 继承Thread类创建线程3.2 实现Runnable接口创建线程 四、Thread类的核心…...
CSS | transition 和 transform的用处和区别
省流总结: transform用于变换/变形,transition是动画控制器 transform 用来对元素进行变形,常见的操作如下,它是立即生效的样式变形属性。 旋转 rotate(角度deg)、平移 translateX(像素px)、缩放 scale(倍数)、倾斜 skewX(角度…...
【网络安全】开源系统getshell漏洞挖掘
审计过程: 在入口文件admin/index.php中: 用户可以通过m,c,a等参数控制加载的文件和方法,在app/system/entrance.php中存在重点代码: 当M_TYPE system并且M_MODULE include时,会设置常量PATH_OWN_FILE为PATH_APP.M_T…...
uniapp 实现腾讯云IM群文件上传下载功能
UniApp 集成腾讯云IM实现群文件上传下载功能全攻略 一、功能背景与技术选型 在团队协作场景中,群文件共享是核心需求之一。本文将介绍如何基于腾讯云IMCOS,在uniapp中实现: 群内文件上传/下载文件元数据管理下载进度追踪跨平台文件预览 二…...
