当前位置: 首页 > news >正文

【从零实现高并发内存池】申请、释放内存过程联调测试 与 大于256KB内存申请全攻略

📢博客主页:https://blog.csdn.net/2301_779549673
📢博客仓库:https://gitee.com/JohnKingW/linux_test/tree/master/lesson
📢欢迎点赞 👍 收藏 ⭐留言 📝 如有错误敬请指正!
📢本文由 JohnKi 原创,首发于 CSDN🙉
📢未来很长,值得我们全力奔赴更美好的生活✨

在这里插入图片描述

在这里插入图片描述

文章目录

  • 🏳️‍🌈一、申请内存过程联调测试
  • 🏳️‍🌈二、释放内存过程联调测试
  • 🏳️‍🌈三、大于256KB内存申请
  • 👥总结


11111111
11111111
11111111
11111111
**** 11111111

测试代码

void TestConcurrentAlloc1() {void* p1 = ConcurrentAlloc(6);void* p2 = ConcurrentAlloc(8);void* p3 = ConcurrentAlloc(1);void* p4 = ConcurrentAlloc(7);void* p5 = ConcurrentAlloc(8);cout << p1 << endl;cout << p2 << endl;cout << p3 << endl;cout << p4 << endl;cout << p5 << endl;ConcurrentFree(p1, 6);ConcurrentFree(p2, 8);ConcurrentFree(p3, 1);ConcurrentFree(p4, 7);ConcurrentFree(p5, 8);
}

🏳️‍🌈一、申请内存过程联调测试

此处进行调试,我们需要调用封装的申请内存函数 ConcurrentAlloc()每个线程第一次调用该函数都会通过TLS获取到自己专属的thread cache对象,然后每个线程就可以通过自己对应的thread cache申请对象了。

static void* ConcurrentAlloc(size_t size)
{// 通过TLS 每个线程无锁的获取自己的专属的ThreadCache对象if (pTLSThreadCache == nullptr){pTLSThreadCache = new ThreadCache;}cout << std::this_thread::get_id() << ":" << pTLSThreadCache << endl;return pTLSThreadCache->Allocate(size);
}

当线程第一次申请内存时,需要通过TLS获取到自己专属的thread cache对象然后通过thread cache对象进行内存申请。

在这里插入图片描述

我们第一个申请的内存大小是 6字节 经过 内存对齐索引查找 后, 最后得到的结果是需要向0号桶中申请8字节的内存

在这里插入图片描述

之后我们会进入慢反馈环节,先计算要向 central cache 申请多少个对象,因为这是第一次申请,所以只需要一个8字节对象


这里需要注意一点

然后满反馈环节发力,下一次申请 2 个对象,在下次申请 3 个,一直到512 个对象为止。 就比如说,我们这里依次创建在0号桶中创建了5个对象(这5个对象的大小都不超过8字节),按 1 + 2 + 3来说,我们就一共申请到了 6 个 8字节 的内存块,所以,当我们释放空间回自由链表的时候,0号桶中还剩余1个内存块

在这里插入图片描述

在thread cache向central cache申请对象之前,需要先将central cache的0号桶的锁加上,然后再从该桶获取一个非空的span。

在这里插入图片描述

central cache第0号桶获取非空span时,先遍历对应的span双链表,看看有没有非空的span,但此时肯定是没有的,只能找 page cache

此时 central cache 就需要向 page cache 申请内存了,但在此之前需要先把central cache第0号桶的锁解掉,然后再将page cache的大锁给加上,之后才能向page cache申请内存。

在这里插入图片描述

在向 page cache 申请内存时,由于 central cache 一次给 thread cache 8字节对象的上限是512,对应就需要4096字节,所需字节数不足一页就按一页算,所以这里central cache就需要向page cache申请一页的内存块。

在这里插入图片描述

此时page cache的第1个桶以及之后的桶当中都是没有span的,因此page cache需要直接向堆申请一个128页的span。

在这里插入图片描述

在这里插入图片描述

而 page cache 向对申请内存的途径就是利用库函数了

在这里插入图片描述

这之后我们就可以观察到,申请到了128页的内存块

在这里插入图片描述

这里的 _PAGEID 的算法可以演示一下,其实就是得到的内存块地址 除上 8K 的大小

在这里插入图片描述

然后我们将这个 128页 直接挂在 pagecache 上,虽然页数为 1 的哈希桶中依然没有内存,但是在页数为 128 的桶中,有刚刚挂上的新内存条

在这里插入图片描述

此时我们就可以把这个128页的span拿出来,切分成1页的span和127页的span将1页的span返回给central cache,而把127页的span挂到page cache的第127号桶即可。

在这里插入图片描述

从page cache返回后,就可以把page cache的大锁解掉了但紧接着还要将获取到的1页的span进行切分,因此这里没有立刻重新加上central cache对应的桶锁。

在这里插入图片描述

在进行切分的时候,先通过该span的起始页号得到该span的起始地址,然后通过该span的页数得到该span所管理内存块的总的字节数。

在这里插入图片描述

在确定内存块的开始和结束后,就可以将其切分成一个个8字节大小的对象挂到该span的自由链表中了。在调试过程中通过内存监视窗口可以看到,切分出来的每个8字节大小的对象的前四个字节存储的都是下一个8字节对象的起始地址

在这里插入图片描述

当切分结束后再开启central cache第0号桶的桶锁,然后将这个切好的span插入到central cache的第0号桶中,最后再将这个非空的span返回,此时就获取到了一个非空的span,并且这个 span 中每 8字节都会有连接

在这里插入图片描述

由于thread cache只向central cache申请了一个对象,因此拿到这个非空的span后,直接从这个span里面取出一个对象即可此时该span的_useCount也由0变成了1。

由于此时thread cache实际只向central cache申请到了一个对象,因此直接将这个对象返回给线程即可。

在这里插入图片描述
然后 p2 申请内存就会申请 2 个对象,在p4申请时又会申请3个对象,以此类推

🏳️‍🌈二、释放内存过程联调测试

刚刚申请完了5个8字节内存,现在将他们释放看看。

调用 thread cachedeallocate 方法

在这里插入图片描述

此时可以看到当我们将第一块内存返回到自由链表时,0号自由链表内的8字节内存块有2块,其中一块是刚刚还回来,另一块是之前p4申请时剩下的那一块

在这里插入图片描述

所以得一直到p3释放时,才会进入 将 自由链表内的过长内存块 还给 central cache 的情况

在这里插入图片描述

thread cache先是将第0号桶当中的对象弹出MaxSize个,在这里实际上就是全部弹出,此时该自由链表_size的值变为0,然后继续调用central cache当中的ReleaseListToSpans函数,将这三个对象还给central cache当中对应的span。

在这里插入图片描述

在进入central cache 的第0号桶还对象之前,先把第0号桶对应的桶锁加上,然后通过查page cache中的映射表找到其对应的span,最后将这个对象头插到该span的自由链表中并将该span的_useCount进行–。当第一个对象还给其对应的span时,可以看到该span的_useCount减到了2。

在这里插入图片描述> 由于我们只进行了 5 次对象申请,并且这些对象大小对齐后大小都是8字节,因此我们申请一个span里的6个块。当我们将这三个对象都还给这个span时,以及多出的那个=一个,该span的_useCount就减为了2。
在这里插入图片描述

但是现在这种情况无法返回给 page cahce,我们需要一个完整的span吗,也就是userCount 为 0 的才可以。于是我们将 创建5 个内存块变成创建 3 个内存块

现在 central cache 就需要将这个 span 进一步还给 page cache,而在将该span交给page cache之前,会将该span的自由链表以及前后指针都置空。并且在进入page cache之前会先将central cache第0号桶的桶锁解掉,然后再加上page cache的大锁,之后才能进入page cache进行相关操作。

在这里插入图片描述

由于这个一页的span是从128页的span的头部切下来的,在向前合并时由于前面的页还未向系统申请,因此在查映射关系时是无法找到的,此时直接停止了向前合并。 同理, 在向后合并时由于后面的页还未向系统申请,因此在查映射关系时是无法找到的,此时直接停止了向后合并

将这个1页的span插入到第1号桶,然后建立该span与其首尾页的映射,便于下次被用于合并,最后再将该span的状态设置为未被使用的状态即可。

在这里插入图片描述

🏳️‍🌈三、大于256KB内存申请

前面说到,每个线程的thread cache是用于申请小于等于256KB的内存的而对于大于256KB的内存,我们可以考虑直接向page cache申请,但page cache中最大的页也就只有128页因此如果是大于128页的内存申请,就只能直接向堆申请了

在这里插入图片描述
注意:当申请的内存大于256KB时,虽然不是从thread cache进行获取,但在分配内存时也是需要进行向上对齐的,对于大于256KB的内存我们可以直接按页进行对齐。

		// 计算对齐后的内存大小static inline size_t RoundUp(size_t size) {if (size <= 128) {return _RoundUp(size, 8); // 对齐到 8 字节}else if (size <= 1024) {return _RoundUp(size, 16); // 对齐到 16 字节}else if (size <= 8 * 1024) {return _RoundUp(size, 128); // 对齐到 128 字节}else if (size <= 64 * 1024) {return _RoundUp(size, 1024);}else if (size <= 256 * 1024) {return _RoundUp(size, 8 * 1024);}else {return _RoundUp(size, 1 << PAGE_SHIFT);}}

对于之前的申请对象的逻辑就需要进行修改了,当申请对象的大小大于256KB时,就不用向thread cache申请了,这时先计算出按页对齐后实际需要申请的页数,然后通过调用NewSpan申请指定页数的span即可。

static void* ConcurrentAlloc(size_t size)
{if (size > MAX_BYTES) {size_t alignSize = SizeClass::RoundUp(size);size_t kpage = alignSize >> PAGE_SHIFT;PageCache::GetInstance()->_pageMtx.lock();Span* span = PageCache::GetInstance()->NewSpan(kpage);PageCache::GetInstance()->_pageMtx.unlock();void* ptr = (void*)(span->_PAGEID << PAGE_SHIFT);return ptr;}// 通过TLS 每个线程无锁的获取自己的专属的ThreadCache对象if (pTLSThreadCache == nullptr){pTLSThreadCache = new ThreadCache;}cout << std::this_thread::get_id() << ":" << pTLSThreadCache << endl;return pTLSThreadCache->Allocate(size);
}

也就是说,申请大于256KB的内存时,会直接调用page cache当中的NewSpan函数进行申请 ,因此这里我们需要再对NewSpan函数进行改造,当需要申请的内存页数大于128页时,就直接向堆申请对应页数的内存块。而如果申请的内存页数是小于128页的,那就在page cache中进行申请,因此当申请大于256KB的内存调用NewSpan函数时也是需要加锁的,因为我们可能是在page cache中进行申请的。

// 获取一个 k 页的 span
Span* PageCache::NewSpan(size_t k) {assert(k > 0);if (k > NPAGES - 1) {void* ptr = SystemAlloc(k);Span* span = new Span;span->_PAGEID = (PAGE_ID)ptr >> PAGE_SHIFT;span->_n = k;_idSpanMap[span->_PAGEID] = span;return span;}// 先检查第 k 个桶里面有没有 spanif (!_spanLists[k].Empty()) {Span* kSpan = _spanLists->PopFront();// 建立 页号 与 span 的映射关系,方便 central cache 回收小块内存查找对应的 spanfor (PAGE_ID i = 0; i < kSpan->_n; ++i) {_idSpanMap[kSpan->_PAGEID + i] = kSpan;}return kSpan;}// 检查一下后面的桶里面有没有 span,如果有可以把他进行切分for (size_t i = k + 1; i < NPAGES; ++i) {// 如果后面的桶里面有 span,这个 span 是肯定大于 k 页的if (!_spanLists[i].Empty()) {// 弹出第 i 个桶的第一个 spanSpan* nSpan = _spanLists[i].PopFront();// 进行切分,切分成一个 k 页的 span 和一个 i-k 页的 spanSpan* kSpan = new Span;kSpan->_PAGEID = nSpan->_PAGEID;kSpan->_n = k;nSpan->_PAGEID += k;nSpan->_n -= k;// 将剩余的代码挂到对应的映射位置上_spanLists[nSpan->_n].PushFront(nSpan);for (PAGE_ID i = 0; i < kSpan->_n; ++i) {_idSpanMap[kSpan->_PAGEID + i] = kSpan;}return kSpan;}}// 走到这个位置就说明后面没有大页的 span 了// 就需要去找堆要一个 128 页的 spanSpan* bigSpan = new Span;// 获取大块内存的起始地址// 假设此时 ptr 地址为 0x010e0000// 转换为 十进制 就是 17,694,720// 17,694,720 / (8 * 1024= 2160// 所以新大内存块的页号就是 2160void* ptr = SystemAlloc(NPAGES - 1);bigSpan->_PAGEID = (PAGE_ID)ptr >> PAGE_SHIFT;bigSpan->_n = NPAGES - 1;_spanLists[bigSpan->_n].PushFront(bigSpan);return NewSpan(k);
}

因此当释放对象时,我们需要先找到该对象对应的span,但是在释放对象时我们只知道该对象的起始地址。这也就是我们在申请大于256KB的内存时,也要给申请到的内存建立span结构,并建立起始页号与该span之间的映射关系的原因。此时我们就可以通过释放对象的起始地址计算出起始页号,进而通过页号找到该对象对应的span。

// 在堆上释放空间
inline static void SystemFree(void* ptr)
{#ifdef _WIN32VirtualFree(ptr, 0, MEM_RELEASE);#else// linux下brk mmap等#endif
}static void ConcurrentFree(void* ptr, size_t size){if (size > MAX_BYTES) {Span* span = PageCache::GetInstance()->MapObjectToSpan(ptr);PageCache::GetInstance()->_pageMtx.lock();PageCache::GetInstance()->ReleaseSpanToPageCache(span);PageCache::GetInstance()->_pageMtx.unlock();}else {assert(pTLSThreadCache);pTLSThreadCache->Deallocate(ptr, size);}
}

因此page cache在回收span时也需要进行判断,t>如果该span的大小是小于等于128页的,那么直接还给page cache就行了,page cache会尝试对其进行合并</fon。而如果该span的大小是大于128页的,那么说明该span是直接向堆申请的,我们直接将这块内存释放给堆,然后将这个span结构进行delete就行了。

void PageCache::ReleaseSpanToPageCache(Span* span) {// 大于 128 page 的直接向堆申请内存,直接释放if (span->_n > NPAGES - 1) {void* ptr = (void*)(span->_PAGEID << PAGE_SHIFT);SystemFree(ptr);delete span;return;}

👥总结

本篇博文对 【从零实现高并发内存池】申请、释放内存过程联调测试 与 大于256KB内存申请全攻略 做了一个较为详细的介绍,不知道对你有没有帮助呢

觉得博主写得还不错的三连支持下吧!会继续努力的~

相关文章:

【从零实现高并发内存池】申请、释放内存过程联调测试 与 大于256KB内存申请全攻略

&#x1f4e2;博客主页&#xff1a;https://blog.csdn.net/2301_779549673 &#x1f4e2;博客仓库&#xff1a;https://gitee.com/JohnKingW/linux_test/tree/master/lesson &#x1f4e2;欢迎点赞 &#x1f44d; 收藏 ⭐留言 &#x1f4dd; 如有错误敬请指正&#xff01; &…...

element-plus添加暗黑模式

main.ts文件 //引入暗黑模式样式 import "element-plus/theme-chalk/dark/css-vars.css"; style.scss文件 // 设置默认主题色 :root {--base-menu-min-width: 80px;--el-color-primary-light-5: green !important;--route--view--background-color: #fff !import…...

第八周作业

1、使用Sqlmap工具完成对DVWA数据库的注入过程&#xff0c;要求按照库、表、列、内容的顺序进行注入 使用kali自带的sqlmap工具进行 (1)爆破库名 sqlmap -u "http://10.0.0.5:8080/vulnerabilities/sqli/?id1&SubmitSubmit#" -p id --cookie "PHPSESSID…...

工作督导 | 具有边缘型人格障碍倾向的高危来访者,咨询师如何应对?

一个学校心理中心&#xff0c;可能同时有几十位乃至数百位同学在接受咨询&#xff0c;其中大约10-20%是重点难点个案&#xff0c;一次督导如果只能督导1-2个个案&#xff0c;不足以保障所有危重难个案的有如何处理恰当、方向正确、快速解决、高效工作&#xff0c;是学校心理咨询…...

c++ map与unordered_map的比较

c map与unordered_map的比较 在c的STL库中&#xff0c;有map与unordered_map这两种名字十分相似的容器&#xff0c;但是他们的区别还是很大&#xff0c;下面我们从 底层实现、性能特性 和 适用场景进行逐一比较 底层实现 std::mapstd::unordered_map底层数据结构红黑树&…...

新手蓝桥杯冲击国一练习题单(四)

2025蓝桥杯省赛已结束&#xff0c;接下来是冲击国赛的时间 此题单为算法基础精选题单&#xff0c;包含蓝桥杯常考考点以及各种经典算法&#xff0c;可以帮助你打牢基础&#xff0c;查漏补缺。 本题单目标是冲击蓝桥杯省一国一&#xff0c;团体程序天梯赛个人国三、XCPC区域赛铜…...

PyTorch深度学习框架60天进阶学习计划 - 第45天:神经架构搜索(一)

PyTorch深度学习框架60天进阶学习计划 - 第45天&#xff1a;神经架构搜索&#xff08;一&#xff09; 第一部分&#xff1a;详解DARTS的可微分搜索空间 大家好&#xff01;欢迎来到我们PyTorch深度学习框架进阶学习计划的第45天。今天我们将深入探讨神经架构搜索(Neural Arch…...

【java 13天进阶Day04】常用API、正则表达式,泛型、Collection集合API

Math类的使用。 Math用于做数学运算。Math类中的方法全部是静态方法&#xff0c;直接用类名调用即可。方法&#xff1a; public static int abs(int a) 获取参数a的绝对值public static double ceil(double a) 向上取整public static double floor(double a) 向下取整public s…...

leetcode 309. Best Time to Buy and Sell Stock with Cooldown

目录 题目描述 第一步&#xff0c;明确并理解dp数组及下标的含义 第二步&#xff0c;分析并理解递推公式 1.求dp[i][0] 2.求dp[i][1] 3.求dp[i][2] 第三步&#xff0c;理解dp数组如何初始化 第四步&#xff0c;理解遍历顺序 代码 题目描述 这道题与第122题的区别就是卖…...

RAG 实战|用 StarRocks + DeepSeek 构建智能问答与企业知识库

文章作者&#xff1a; 石强&#xff0c;镜舟科技解决方案架构师 赵恒&#xff0c;StarRocks TSC Member &#x1f449; 加入 StarRocks x AI 技术讨论社区 https://mp.weixin.qq.com/s/61WKxjHiB-pIwdItbRPnPA RAG 和向量索引简介 RAG&#xff08;Retrieval-Augmented Gen…...

Java拼团项目

一些记录 环境配置 首先是把配置安装好&#xff0c;jdk1.8&#xff0c;maven3.8.8&#xff0c;docker&#xff0c;idea&#xff0c;脚手架 然后创建工程&#xff0c;通过小傅哥的脚手架从远程把一些包&#xff0c;依赖拉过来 然后在gitcode上边创建仓库&#xff0c;把代码提交…...

力扣每日打卡 2364. 统计坏数对的数目 (中等)

力扣 2364. 统计坏数对的数目 中等 前言一、题目内容二、解题方法1. 哈希函数12. 哈希函数22.官方题解2.1 方法一&#xff1a;使用 sqrt 函数 前言 这是刷算法题的第十四天&#xff0c;用到的语言是JS 题目&#xff1a;力扣 2364. 统计坏数对的数目 (中等) 一、题目内容 给你…...

R语言之.rdata文件保存及加载

在 R 中&#xff0c;.rdata 文件是通过 save() 函数创建的。 使用 save() 函数可以将一个或多个 R 对象保存到 .rdata 文件中。使用 load() 函数可以将 .rdata 文件中的对象恢复到当前工作环境中。 1.创建并保存对象到.rdata 假设有一个基于 iris 数据集训练的线性回归模型&a…...

神经网络优化 - 小批量梯度下降之批量大小的选择

上一博文学习了小批量梯度下降在神经网络优化中的应用&#xff1a; 神经网络优化 - 小批量梯度下降-CSDN博客 在小批量梯度下降法中&#xff0c;批量大小(Batch Size)对网络优化的影响也非常大&#xff0c;本文我们来学习如何选择小批量梯度下降的批量大小。 一、批量大小的…...

开源AI守护每一杯------奶茶咖啡店视频安全系统的未来之力

连锁饮品奶茶咖啡店视频安全系统以开源AI技术为引擎&#xff0c;将后厨管理从“被动查漏”升级为“主动防控”&#xff0c;让消费者从“担心卫生”变为“放心下单”。 解决方案亮点&#xff1a;技术驱动&#xff0c;全面防护 1. 实时监控与AI识别&#xff1a;秒级捕捉隐患 亮…...

音视频元素

目录 HTMLMediaElement网络状态 (networkState)就绪状态 (readyState)错误代码 (error.code) video属性方法事件 audio HTMLMediaElement HTMLMediaElement 是 HTML5 中 和 元素的基类&#xff0c;定义了它们共享的属性、方法和事件。无论你使用的是音频还是视频元素&#xff0…...

音视频小白系统入门课-2

本系列笔记为博主学习李超老师课程的课堂笔记&#xff0c;仅供参阅 课程传送门&#xff1a;音视频小白系统入门课 音视频基础ffmpeg原理 往期课程笔记传送门&#xff1a; 音视频小白系统入门笔记-0音视频小白系统入门笔记-1 课程实践代码仓库&#xff1a;传送门 音视频编解…...

时序逻辑电路——序列检测器

文章目录 一、序列检测二、牛客真题1. 输入序列连续的序列检测&#xff08;输入连续、重叠、不含无关项、串行输入&#xff09;写法一&#xff1a;移位寄存器写法二&#xff1a;Moore状态机写法三&#xff1a;Mealy状态机 一、序列检测 序列检测器指的就是将一个指定的序列&…...

#systemverilog# 进程控制问题#(八)关于#0 问题的使用(三)

今天,我们继续研究一下上一节讨论的问题。其实,还有一个小问题,我们来探讨一下。 `timescale 1ns/10psmodule tb_top(); reg clk; reg reset;initial begin reset = 0; #10 reset = 1; #15 reset = 0; #50 $finish; endinitial beginfor(int i = 0; i < 4 ; i++)fork #…...

k8s低版本1.15安装prometheus+grafana进行Spring boot数据采集

目录 一、背景&#xff1a; 二、实施过程 1&#xff09;.安装地址&#xff1a;https://github.com/prometheus-operator/kube-prometheus 2).安装方式两种&#xff0c; 3&#xff09;.安装Prometheus需要对照k8s集群版本。 4&#xff09;.拉去prometheus 5&#xff09;.导…...

Spring-Ioc容器的加载过程?

大家好&#xff0c;我是锋哥。今天分享关于【SpringIoC的实现机制是什么&#xff1f;】面试题。希望对大家有帮助&#xff1b; Spring-Ioc容器的加载过程&#xff1f; 1000道 互联网大厂Java工程师 精选面试题-Java资源分享网 Spring IoC容器的加载过程是指在应用启动时&…...

kaamel Privacy agent:AI赋能的隐私保护技术解决方案

智能隐私合规解决方案 在当今数字经济环境下&#xff0c;有效的隐私合规已成为企业运营的基础要求。全球范围内已有超过120项隐私法规生效&#xff0c;这对企业的数据处理流程提出了严峻挑战。kaamel Privacy agent作为专门为隐私合规领域设计的AI引擎&#xff0c;通过自动化技…...

从零到上线!AI生成SpringBoot项目脚手架实战(含K8s+Docker配置)

在 Java 开发领域,搭建 Spring Boot 项目脚手架是一项耗时且繁琐的工作。传统方式下,开发者需要手动配置各种依赖、编写基础代码,过程中稍有疏忽就可能导致配置错误,影响开发进度。如今,随着 AI 技术的迅猛发展,飞算 JavaAI 的出现为开发者带来了全新解决方案,让自动生成 Sprin…...

VueRouter笔记

定义路由 import { createMemoryHistory, createRoute } from vue-router; import MyView1 from ./MyView1.vue; import MyView2 from ./MyView2.vue;const routes [{ path: /1, component: MyView1 },{ path: /2, component: MyView2 } ];const router createRouter({histo…...

vue3 Element-plus修改内置样式复现代码

笔者在修改Element-plus的内置样式时&#xff0c;遇到一点挫折&#xff0c;现提供需求场景与解决方案。 一、实现&#xff08;1&#xff09;透明弹窗可拖拽&#xff0c;且不影响点击弹窗外内容&#xff1b;&#xff08;2&#xff09;弹窗内置表格&#xff0c;表格需修改样式颜色…...

easyui进度条

简单打开和关闭 // 展示进度条 $.messager.progress({title: 请稍候,msg: 系统处理中...,text: 0%});//关闭进度条 $.messager.progress(close); easyui 普通提示 <!DOCTYPE html> <html> <head><meta charset"UTF-8">&l…...

vcpkg缓存问题研究

vcpkg缓存问题研究 问题描述解决方案官网给出的方案其实并不是大多数人语境中的“清除缓存”实际解决方案 问题描述 使用vcpkg管理c的库的时候&#xff0c;vcpkg会在c盘某些地方缓存下载的库&#xff0c;如果安装的库过多&#xff0c;这个缓存文件夹会过大占用磁盘空间&#x…...

优化WAV音频文件

优化 WAV 音频文件通常涉及 减小文件体积、提升音质 或 适配特定用途&#xff08;如流媒体、广播等&#xff09;。以下是分场景的优化方法&#xff0c;涵盖工具和操作步骤&#xff1a; 一、减小文件体积&#xff08;无损/有损压缩&#xff09; 1. 无损压缩 转换格式&#xff1…...

系统架构设计师:流水线技术相关知识点、记忆卡片、多同类型练习题、答案与解析

题目&#xff1a; 流水线技术中&#xff0c;若某流水线分为5段&#xff0c;每段执行时间为Δt&#xff0c;则执行100条指令的总时间为&#xff08; &#xff09; A. 100Δt B. 104Δt C. 500Δt D. 505Δt 答案&#xff1a;B‌ ‌解析&#xff1a;流水线总时间(nk-1)Δt&#…...

test ssl java

// 文件名&#xff1a;SslUtilsTest.java// 包路径&#xff1a; import static org.junit.Assert.*; import static org.mockito.Mockito.*; import java.io.InputStream; import java.security.KeyStore; import javax.net.ssl.SSLContext; import org.apache.hc.client5…...

【系统分析师】-软件工程

考点汇总 考点详情 软件生存周期&#xff1a;可行性分析与项目开发计划&#xff0c;需求分析&#xff0c;概要设计&#xff0c;详细设计&#xff0c;编码&#xff0c;测试&#xff0c;维护 软件能力成熟度模型 CMM&#xff1a;初始级&#xff0c;可重复级&#xff0c;已定义级…...

FFmpeg 硬核指南:从底层架构到播放器全链路开发实战 基础

目录 1.ffmpeg的基本组成2.播放器的API2.1 复用器阶段2.1.1 分配解复用上下文2.1.2 文件信息操作2.1.3 综合示例 2. 2 编解码部分2.2.1 分配解码器上下文2.2.2编解码操作2.2.3 综合示例 3 ffmpeg 内存模型3.1 基本概念3.2API 1.ffmpeg的基本组成 模块名称功能描述主要用途AVFo…...

2025MathorcupD题 短途运输货量预测及车辆调度问题 保姆级教程讲解|模型讲解

2025Mathorcup数学建模挑战赛&#xff08;妈妈杯&#xff09;D题保姆级分析完整思路代码数据教学 其中更详细的思路&#xff0c;各题目思路、代码、讲解视频、成品论文及其他相关内容&#xff0c;可以点击下方群名片哦&#xff01;...

CSS 包含块

CSS 中的包含块&#xff08;Containing Block&#xff09;是一个非常重要的概念&#xff0c;它定义了元素在布局中的参考框架。元素的尺寸、位置和偏移量通常都是基于其包含块来计算的。理解包含块的概念对于掌握 CSS 布局至关重要。 1. 包含块的作用 定位元素&#xff1a;当…...

嵌入式设备网络的动态ID分配机制实现

文章目录 前言一、系统设计要点二、核心数据结构2.1 设备唯一标识(DeviceUID)2.2 节点信息(Node)2.3 节点管理器(NodeManager) 三、核心算法实现3.1 初始化与清理3.1.1 初始化节点管理器3.1.2 清理节点管理器 3.2 动态ID分配策略3.2.1 查找最小可用ID3.2.2 ID使用检查 3.3 心跳…...

(论文阅读)RNNoise 基于递归神经网络的噪声抑制库

RNNoise 是一个基于递归神经网络的噪声抑制库。 有关该算法的描述见以下论文&#xff1a; J.-M. Valin, A Hybrid DSP/Deep Learning Approach to Real-Time Full-Band Speech Enhancement, Proceedings of IEEE Multimedia Signal Processing (MMSP) Workshop, arXiv:1709.08…...

Linux:线程概念与控制

✨✨所属专栏&#xff1a;Linux✨✨ ✨✨作者主页&#xff1a;嶔某✨✨ Linux&#xff1a;线程概念于控制 var code “d7e241ae-ed4d-475f-aa3d-8d78f873fdca” 概念 在一个程序里的一个执行路线就叫做线程thread。更准确一点&#xff1a;线程是“一个进程内部的控制序列” …...

双轮驱动能源革命:能源互联网与分布式能源赋能工厂能效跃迁

在全球能源结构深度转型与“双碳”目标的双重驱动下&#xff0c;工厂作为能源消耗的主力军&#xff0c;正站在节能变革的关键节点。能源互联网与分布式能源技术的融合发展&#xff0c;为工厂节能开辟了全新路径。塔能科技凭借前沿技术与创新实践&#xff0c;深度探索能源协同优…...

网络安全-Burp Suite基础篇

声明 本文主要用做技术分享&#xff0c;所有内容仅供参考。任何使用或者依赖于本文信息所造成的法律后果均与本人无关。请读者自行判断风险&#xff0c;并遵循相关法律法规。 1 Burp Suite功能介绍 1.1 Burp Suite 简介 Burp Suite 是一款极为强大且广受欢迎的集成化 …...

从人工到智能:外呼系统如何重构企业效率新生态

在数字化转型的浪潮中&#xff0c;智能外呼系统正从边缘辅助工具演变为企业效率革命的核心引擎。根据Gartner最新调研数据&#xff0c;部署AI外呼系统的企业客服效率平均提升68%&#xff0c;销售线索转化率增长42%。但在这场技术驱动的变革中&#xff0c;真正决定成败的往往不是…...

折扣电影票api对接详细指南,如何对接?

以下是折扣电影票 API 对接的一般指南&#xff1a; 对接前准备 明确需求&#xff1a;确定对接的目的和所需功能&#xff0c;如电影信息查询、场次查询、座位预订、支付等。明确支持的数据字段和业务流程。选择 API 服务提供商&#xff1a;选择技术成熟、服务稳定、覆盖范围广的…...

初识Redis · 客户端“Hello world“

目录 前言&#xff1a; 环境配置 Hello world 前言&#xff1a; 前文我们已经介绍了Redis的不常见的五种数据类型&#xff0c;并且补充了几个渐进式命令和数据库管理命令等&#xff0c;最后简单认识了一下RESP协议&#xff0c;但是老实说&#xff0c;我们只能算是知道了这个…...

51单片机实验一:点亮led灯

目录 一、实验环境与实验器材 二、实验内容及实验步骤 1.用keil 软件创建工程&#xff0c;C文件编写程序&#xff0c;编译生成hex文件​编辑 2.用STC烧写hex文件&#xff0c;点亮第一个LED灯 3.使用法2&#xff0c;点除第一个以外的LED灯 一、实验环境与实验器材 环境&am…...

基于WOA鲸鱼优化的NARMAX模型参数辨识算法MATLAB仿真,对比PSO优化算法

目录 1.程序功能描述 2.测试软件版本以及运行结果展示 3.核心程序 4.本算法原理 4.1 NARMAX模型定义 4.2 鲸鱼优化算法WOA原理 4.3 粒子群优化算法PSO原理 5.完整程序 1.程序功能描述 基于WOA鲸鱼优化的NARMAX模型参数辨识算法MATLAB仿真,对比PSO优化算法。分别通过WOA…...

AWS上构建基于自然语言的数值和符号计算系统

我想要实现一个通过使用C#、Semantic Kernel库、OpenAI GPT 4的API和以下使用C#开源库MathNet实现通过中文自然语言提示词中包含LATEX代码输入到系统,通过以下符号和数值计算和其它符号和数值计算程序输出计算结果和必要步骤的应用,这样的数学计算使用程序直接产生结果,可以…...

2025年03月中国电子学会青少年软件编程(Python)等级考试试卷(三级)真题

青少年软件编程&#xff08;Python&#xff09;等级考试试卷&#xff08;三级&#xff09; 分数&#xff1a;100 题数&#xff1a;38 答案解析&#xff1a;https://blog.csdn.net/qq_33897084/article/details/147341388 一、单选题(共25题&#xff0c;共50分) 1. 学校进行体…...

校平机:精密制造的“材料雕刻家“

在液晶面板生产线的无尘车间里&#xff0c;一片薄如蝉翼的玻璃基板正经历纳米级的形态修正&#xff1b;在新能源电池极片生产线上&#xff0c;铜箔以每秒5米的速度穿越精密辊系&#xff0c;完成微米级的平整蜕变。这些现代工业的"毫米级魔术"&#xff0c;都离不开一台…...

FPGA HR Bank如何支持ODELAY问题分析

目录 1.ODELAY简单介绍 2.IODELAY 的特性 3.IODELAY 的 资源支持的管脚 4.HR bank如何支持ODELAY固定延迟 1.ODELAY简单介绍 FPGA 中的 IODELAY(Input/Output Delay),这是 Xilinx(现 AMD)FPGA 中一种用于精确控制输入/输出信号时序延迟的硬件资源。以下是关于 IODELAY…...

深入解析C++驱动开发实战:优化高效稳定的驱动应用

深入解析C驱动开发实战&#xff1a;优化高效稳定的驱动应用 在现代计算机系统中&#xff0c;驱动程序&#xff08;Driver&#xff09;扮演着至关重要的角色&#xff0c;作为操作系统与硬件设备之间的桥梁&#xff0c;驱动程序负责管理和控制硬件资源&#xff0c;确保系统的稳定…...

高级java每日一道面试题-2025年4月13日-微服务篇[Nacos篇]-Nacos如何处理网络分区情况下的服务可用性问题?

如果有遗漏,评论区告诉我进行补充 面试官: Nacos如何处理网络分区情况下的服务可用性问题&#xff1f; 我回答: 在讨论 Nacos 如何处理网络分区情况下的服务可用性问题时&#xff0c;我们需要深入理解 CAP 理论以及 Nacos 在这方面的设计选择。Nacos 允许用户根据具体的应用…...