一、背景

在客户测试环境中(GaussDB 506.0 SPC0100 集中式),一个重度使用存储过程的系统,频繁出现内存临时不可用的问题(ERROR: memory is temporarily unavailable)。令人困惑的是,这个环境配置的内存大小已经数十倍于迁移前的Oracle。


二、GaussDB提供的观测方法

GaussDB官方产品文档中有一个《内存过载》章节,详细描述了在出现内存过载情况下如何定位,但似乎这个章节并没有在官方网站上公开。下面按照本次分析过程进行描述。

内存监控视图

GaussDB提供了几个重要的内存视图:

gs_total_memory_detail
显示当前数据库节点的内存使用情况,单位为MB。当GUC参数enable_memory_limit的值为off时,本视图不可用。

gs_session_memory_detail
显示会话的内存使用情况,以MemoryContext节点来统计。当开启线程池(enable_thread_pool = on)时,该视图包含所有线程和会话的内存使用情况。当GUC参数enable_memory_limit的值为off时,本视图不可用。

gs_shared_memory_detail
查询当前节点所有已产生的共享内存上下文的使用信息。

内存使用情况示例

SELECT * FROM gs_total_memory_detail;

nodenamememorytypememorymbytes
primarymax_process_memory24567
primaryprocess_used_memory7847
primarymax_dynamic_memory16651
primarydynamic_used_memory1843
primarydynamic_peak_memory2942
primarydynamic_used_shrctx1286
primarydynamic_peak_shrctx1387
primarymax_backend_memory1360
primarybackend_used_memory1
primaryhigh_backend_thread_memory20
primaryhigh_backend_thread_max_memory768
primarymedium_backend_thread_memory113
primarymedium_backend_thread_max_memory1536
primarylow_backend_thread_memory0
primarylow_backend_thread_max_memory768
primarymax_shared_memory6548
primaryshared_used_memory5402
primarymax_cstore_memory16
primarycstore_used_memory0
primarymax_sctpcomm_memory0
primarysctpcomm_used_memory0
primarysctpcomm_peak_memory0
primaryother_used_memory527
primarygpu_max_dynamic_memory0
primarygpu_dynamic_used_memory0
primarygpu_dynamic_peak_memory0
primarypooler_conn_memory0
primarypooler_freeconn_memory0
primarystorage_compress_memory0
primaryudf_reserved_memory0
primaryllvm_used_memory0
primarymax_htap_memory0
primaryhtap_used_memory0


内存类型理解指南

要真实理解gs_total_memory_detail里这些内存类型的关系,并且理解gs_session_memory_detail和gs_shared_memory_detail记录的内存对应到gs_total_memory_detail的映射关系,需要明确以下几点:


内存指标含义


max:表示最大可以为多少,超过就会报内存不足
used:表示当前已经申请了多少
peak:表示本次数据库启动以来的历史used峰值


内存分配关系


max_process_memory 是通过参数设置的
max_shared_memory主要为shared_buffers,但是这个值的大小可能会比shared_buffers要大
max_dynamic_memory是 max_process_memory - max_shared_memory - max_cstore_memory - max_backend_memory - ... 得到的
dynamic_used_memory 包括了:

动态会话内存(gs_total_memory_detail里没列出来)
dynamic_used_shrctx
high_backend_thread_memory
medium_backend_thread_memory
low_backend_thread_memory
💡 注意:后三个high/medium/low暂时不用关心,这是新版本中引入的特性,为后台线程专门分出来的内存。


GaussDB内存区域划分

在GaussDB中,主要的内存区域分为:

📁 共享内存(主要为shared_buffers)
📁 动态内存(dynamic_memory)
├── 📄 动态会话内存 (gs_session_memory_detail)
├── 📄 动态共享内存 (dynamic_used_shrctx) (gs_shared_memory_detail)
└── 📄 动态后台内存
⚠️ 重要提醒:这里出现两个"共享内存",非常容易产生理解上的歧义。比如gs_shared_memory_detail这个视图,查的就不是"共享内存",而是"动态共享内存"。

可以这么理解:

shared_buffers主要是data buffer,即表和索引的数据
GaussDB实现的global plan cache/global plsql cache/unique sql hash table等全局缓存,并不属于shared_buffers,而是在dynamic_used_shrctx里

内存追踪配置

内存不足的报错经常是一个瞬间冲高,回头再来看这些视图时,已经找不到对应的内存上下文,因此GaussDB在出现内存不足的报错时,会自动把当时的内存上下文情况生成到单独的日志文件中。

memory_trace_level 参数
参数说明:动态内存使用超过最大动态内存的90%后,记录内存申请信息的管控等级。该参数仅在GUC参数use_workload_manager和enable_memory_limit打开时生效。

参数类型:枚举类型

参数单位:无

取值范围:

级别说明
none表示不记录内存申请信息
level1动态内存使用超过最大动态内存的90%后,会记录以下信息,并将记录的内存信息保存在$GAUSSLOG/mem_log目录下:
• 全局内存概况
• instance,session,thread三种类型的所有内存上下文中内存占用前20的内存上下文的内存使用情况
• 每个内存上下文的totalsize、freesize字段
level2在level1的基础上,还会记录每个内存上下文上所有内存申请的详细信息,包含申请内存所在的文件,行号和大小


默认值:level1

⚠️ 设置建议:该参数设置为level2后,会记录每个内存上下文的内存申请详情(file,line,size字段),会对性能影响较大,需慎重设置。

相关功能:

记录的内存快照信息可以通过系统函数gs_get_history_memory_detail(cstring)查询
记录的内存上下文是经过将同一类型所有重名的内存上下文进行汇总之后得到的


三、现场分析

初步发现

由于默认是level1,没有记录申请内存的源码文件和行号,因此后面现场调成了level2。
当时的mem_log中有记录两个比较可疑的内存上下文:

位置上下文名称数量大小
shared_memoryunique sql hash table1个~8G
session_memorySRF multi-call contex1个~8G


然后回头查gs_shared_memory_detail、gs_session_memory_detail这两个视图,发现的确可以查到unique sql hash table占了8G,但是查不到SRF multi-call context。

监控脚本

客户DBA写了个监控脚本,每隔20秒采集一下各个内存视图的数据。

但几天后,仍然没有采集到SRF multi-call context,而数据库日志中仍然会时不时报错内存临时不可用。

关键发现

在一次偶然的连续查询gs_total_memory_detail时,发现已使用的动态内存上下波动幅度高达8GB。

于是猜想可能是一个非常短的时间产生了SRF multi-call context这个上下文,执行完后就释放了,所以间隔20秒采一次能采到的概率非常低。

深入分析

数据库大厂的内核研发往往都只负责各自一小块领域,华为内核研发远程查看日志,并没有发现什么可疑的点,而且还拉了好几个不同领域的内核研发,都没有找到原因。

但是在远程会议中,客户快速一页一页翻日志时,我发现一个现象:

在出现内存临时不可用报错的前面一段,会频繁打印相同格式的日志,而且中间有个数字一直在涨,从1XXXXXXXXX一直涨到7XXXXXXXXX,然后就没有这个重复日志了。

直觉告诉我,很可能与这个有关。于是让客户回到这段日志前面,然后发现了类似下面的这么一行:

2025-07-25 10:00:01.523 primary RdsAdmin postgres xxx.xxx.xxx.xxx 140216907527936 12[0:0#0] 0 gsql 00000 31806672368306287 [BACKEND] LOG:  00000: unique_sql_id=3740540431, Current SQL is consuming about 1099 MB, allocating 102921000 bytes, memctx:SRF multi-call context, appname:, user_id: 16616, current query is: select usename,count(*) from dbe_perf.statement group by usename

问题串联

很明显这里就出现了SRF multi-call context,然后这段日志下面就是不断地在申请内存,直到申请了8G,后面很快就有一个业务调用存储过程报错内存不足了。

也就是说,在这个环境中,查询一次dbe_perf.statement这个视图,就会申请8G内存。这个查询,是TPOPS端定时采集的SQL。

dbe_perf.statement这个视图里实际上是一个查询特定内存数据的返回多行的函数,查询的就是unique sql hash table里的内容。

问题链条分析

分析到这里,感觉大部分疑点都串起来了:

由于某种原因,归一化SQL的内存达到了8G
然后由于TPOPS定时查询dbe_perf.statement,导致内存瞬间又消耗了8GB
光这两个动态内存上下文就占了16GB
由于这是个重度存储过程的系统,GLOBAL PLSQL CACHE又占了几个GB
动态内存全用完了,导致业务会话报错

进一步探究

归一化内存为什么会达到8GB?

我在很早就问过华为内核研发:track_activity_query_size=40960这么设置,如果SQL没达到这个长度,占用的内存是SQL实际的长度还是40960?

我一直记得在openGauss系数据库中,这个内存一定是按设置的这个大小申请,不会根据SQL实际长度变化,但是华为内核研发说在GaussDB中内存占用只会按实际SQL长度来,除非SQL长度达到或者超过这个数,才会申请这么多内存。

由于GaussDB并没有开源,所以当时我只能相信华为说的,可能GaussDB做了优化。

巧合的乘积

可是客户现场出现这个现象时,我直接计算了下:

40,960 × 200,000 = 8,192,000,000

刚好差不多8G,这么巧合?

然后客户也查了,实际在dbe_perf.statement里query的汇总字节数,也就只有一百多MB。

但是华为内核研发说他看了那段代码,说的确是按实际长度来的,但是他又无法解释这8GB到哪里去了,因为算上其他属性的长度,每行最多就再加几百KB。


四、问问万能的AI

GaussDB没开源,但是openGauss是开源的,本来想用Cursor来分析一下,奈何被断供了,只能先用vscode的Copilot了。

打开openGauss源码目录,切换Copilot到agent模式,开问:

第一轮提问
Dark-Athena: 看下SRF multi-call context 这个上下文在什么时候会产生

GitHub Copilot :内容较长具体可点击文末左下角查看原文获取


总结:SRF multi-call context 在任何集合返回函数第一次被调用时产生,用于在函数的多次调用之间保持状态和数据,直到函数返回完所有结果后被清理。

第二轮提问
Dark-Athena: 分析下执行get_instr_unique_sql这个函数时,申请的"SRF multi-call context"占用大小与什么有关

GitHub Copilot: 内容较长具体可点击文末左下角查看原文获取

在生产环境中,建议根据实际的 SQL 多样性和系统内存容量合理配置 instr_unique_sql_count 和 pgstat_track_activity_query_size 参数,以平衡监控精度和内存占用。

第三轮关键提问
Dark-Athena: 如果我一条SQL的长度没达到pgstat_track_activity_query_size,也会申请pgstat_track_activity_query_size这个值大小的内存么?

GitHub Copilot: 内容较长具体可点击文末左下角查看原文获取

所以答案是肯定的:即使你的SQL很短(比如SELECT 1;),系统仍然会为每个后端进程的st_activity字段分配完整的pgstat_track_activity_query_size大小的内存空间。


五、结论分析

结合AI的分析,可以得出以下结论:

核心发现

1、固定内存分配

track_activity_query_size是固定会申请的内存大小
占用的内存大小不会由于SQL比这个值小而减小
实际单个unique sql所占用的空间,会比track_activity_query_size还要大一些
当instr_unique_sql_count为GaussDB默认的200000,track_activity_query_size为40960时,unique sql hash table能达到8GB

2、SRF函数特性

SRF函数就是返回多行的函数
dbe_perf.statement里就是一个SRF函数
为了在返回多行时保持数据稳定性,就会把查询结果全存到内存里,直到查询完才释放

3、内存复制机制

dbe_perf.statement查的就是unique sql hash table的内容
SRF为了数据稳定性,几乎把这8GB的内存复制了一份,放到了SRF multi-call context里

深层问题探究

看上去这就是个非常低级的问题?但是问题还没完:

为什么unique sql会那么快达到200000个?

这个环境才刚部署没几天,而且都是跑的存储过程,没有什么拼接SQL,理论上SQL数是稳定有限的。

通过截取statement.query前200个字符进行group by计数排序,发现很大一部分SQL都是一个declare开头的自治事务匿名块。

根本原因

由于我之前和openGauss社区的研发一起分析过plsql编译依赖这个功能的问题,当时为了解决编译时数据字典表锁释放的问题,我提出了可以起个自治事务去编译,这样能避免长时间持有元数据锁的问题。而GaussDB也是用的这个方案(巧合?)。

所以我一眼就看出来GaussDB里记录的这些SQL是在做存储过程编译,但是GaussDB把整个存储过程的内容都放到这个匿名块里了,而且还有一些oid信息,因此必然是不同的SQL。

这个匿名块还会做一些数据字典的DML操作,这些DML的SQL是固定不变的,大概有6~7条。再来就是dbe_perf.statement里,对于parent_unique_sql_id不同的同一个unique_sql_id,会视为不同的记录。

问题链条完整梳理

存储过程编译:每次改一个存储过程,就在dbe_perf.statement里生成了约10条的记录
重复生成:反复改就反复生成,有时候全量存储过程重建,数字唰唰唰就涨上去了
资源耗尽:200000也经不起这么耗,真正的业务SQL可能还会计不进去了
内存占用:全是存储过程编译时自动产生的这些SQL

目前客户这边只能先调小track_activity_query_size到4K,让dbe_perf.statement的内存占得小些,至少让业务测试能继续进行下去。

六、复现方法

诊断了这么多天的问题,弄清楚原理后,非常容易复现unique sql hash table和SRF multi-call context申请大量内存的现象:

环境配置

-- 这个是单个会话的unique sql上限,由于模拟测试都在一个会话里,所以要调大

gs_guc reload -c "track_stmt_session_slot=200000"

-- 直接设置到最大值,内存涨得最快

gs_guc reload -c "track_activity_query_size=102400"

-- 重启,释放 unique sql 内存

gs_ctl restart

测试脚本

-- 构造不同的SQL
-- 注意GaussDB对于表别名或字段别名不同、常量不同的也会进行归一化
-- 所以这里直接用不同的对象名

DECLAREx_sql1 text;x_sql2 text;i int;
BEGIN
FOR i IN1..5000
LOOPx_sql1 := 'CREATE TABLE t_abcd'||i||'(a int);';x_sql2 := 'DROPTABLE t_abcd'||i;EXECUTE IMMEDIATE x_sql1;EXECUTE IMMEDIATE x_sql2;END LOOP;RAISE NOTICE '%', x_sql1;
END;
/

验证结果

-- 查询动态共享内存里unique sql hash table的大小

SELECTcontextname,
count(1),
ROUND(sum(totalsize)/1024/1024,2) AS TOTALSIZE_MB,
ROUND(Sum(usedsize)/1024/1024) AS usedsize_MB 
FROM GS_shared_MEMORY_DETAIL  
GROUPBY contextname 
ORDERBY3DESC
LIMIT10;
contextnamecounttotalsize_mbusedsize_mb
unique sql hash table11468.751469
DefaultTopMemoryContext1172.5760
ASP unique sql hash table182.1182


unique sql hash table占1个多GB
-- 查询SQL实际长度所占的空间,和按track_activity_query_size的长度计算的空间

SELECT
sum(lengthb(query))/1024/1024AS actual_size_mb,(count(1)*current_setting('track_activity_query_size')::int)/1024/1024AS allocated_size_mb
FROM dbe_perf.statement;
actual_size_mballocated_size_mb
0.381401.07


按track_activity_query_size来算,也是1个多GB。
日志验证

执行查询后,日志中出现SRF multi-call context:

2025-07-25 10:00:01.523 primary admin postgres 172.17.0.1 140216907527936 12[0:0#0] 0 Mogeaver 23.3.1 - SQLEditor <Script-22.sql> 00000 31806672368306287 [BACKEND] LOG:  00000: unique_sql_id=3740540431, Current SQL is consuming about 1099 MB, allocating 102921000 bytes, memctx:SRF multi-call context, appname:, user_id: 16616, current query is: select sum( lengthb(query) )/?/?,(count(?)*current_setting(?)::int)/?/? from dbe_perf.statement
2025-07-25 10:00:01.523 primary admin postgres 172.17.0.1 140216907527936 12[0:0#0] 0 Mogeaver 23.3.1 - SQLEditor <Script-22.sql> 00000 31806672368306287 [BACKEND] LOCATION:  mmgr_memory_check_reach_one_gb, framework_memory_memctrl_util.cpp:241
2025-07-25 10:00:01.523 primary admin postgres 172.17.0.1 140216907527936 12[0:0#0] 0 Mogeaver 23.3.1 - SQLEditor <Script-22.sql> 00000 31806672368306287 [INSTR] LOG:  00000: [UniqueSQL] idx[10] - new memory allocated: 102921000
2025-07-25 10:00:01.523 primary admin postgres 172.17.0.1 140216907527936 12[0:0#0] 0 Mogeaver 23.3.1 - SQLEditor <Script-22.sql> 00000 31806672368306287 [INSTR] LOCATION:  unique_sql_log_result_mem, instr_unique_sql.cpp:1407
2025-07-25 10:00:01.524 primary admin postgres 172.17.0.1 140216907527936 12[0:0#0] 0 Mogeaver 23.3.1 - SQLEditor <Script-22.sql> 00000 31806672368306287 [INSTR] LOG:  00000: [UniqueSQL] total memory allocated: 1132131000
2025-07-25 10:00:01.524 primary admin postgres 172.17.0.1 140216907527936 12[0:0#0] 0 Mogeaver 23.3.1 - SQLEditor <Script-22.sql> 00000 31806672368306287 [INSTR] LOCATION:  unique_sql_log_result_mem, instr_unique_sql.cpp:1408

七、总结-经验教训

1、经验的积累非常重要

国产数据库使用过程中肯定会发现很多新问题,其中有一些综合性的问题,原厂的内核研发都不一定能找到原因,具备综合技能的DBA能从现场的蛛丝马迹结合长期的工作经验所产生的直觉,来发现问题症结所在

2、知识的积累非常重要

如果连内存区域都分不清,就算数据库已经提供了很多方法来进行诊断,面对本文这个问题,脑子里只能是一团浆糊

3、需要学会借助AI

现在的AI有了agent,能自动且快速完成很多事,本文中就让AI自动翻源码分析,对问题进行了快速定位

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

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

相关文章

LeeCode 40.组合总和II

给定一个候选人编号的集合 candidates 和一个目标数 target &#xff0c;找出 candidates 中所有可以使数字和为 target 的组合。candidates 中的每个数字在每个组合中只能使用 一次 。注意&#xff1a;解集不能包含重复的组合。 示例 1:输入: candidates [10,1,2,7,6,1,5], t…

数据结构:队列 二叉树

队列&#xff08;Queue&#xff09; 是一种先进先出&#xff08;First In First Out, FIFO&#xff09; 的线性数据结构。 队列的基本特性 1. FIFO 原则 • 最先进入的元素最先出去 • 就像现实生活中的排队&#xff1a;先来的人先接受服务 2. 两个主要操作端 • 队尾&#xff…

FTP工作原理及搭建实操

文章目录前言一、FTP概述二、FTP工作原理2.1 FTP的作用与模式2.2 FTP工作流程2.2.1 主动模式&#xff08;PORT模式&#xff09;2.2.2 被动模式&#xff08;PASV模式&#xff09;2.2.3 对比表格2.2.4 如何选择&#xff1f;2.2.5 补充&#xff1a;现代FTP服务器的常见做法三、FTP…

setup 语法糖核心要点

1. 基本语法<!-- 传统写法 --> <script lang"ts"> export default {setup() {let name 张三function changeName() { name 李四 }return { name, changeName }} } </script><!-- 语法糖写法 --> <script setup lang"ts"> …

C++---多态(一个接口多种实现)

C的多态&#xff08;Polymorphism&#xff09;是面向对象编程&#xff08;OOP&#xff09;的三大核心特性之一&#xff08;另外两个是封装和继承&#xff09;&#xff0c;其核心思想是一个接口&#xff0c;多种实现&#xff0c;即同一操作作用于不同对象时&#xff0c;可产生不…

【机器学习深度学习】vLLM的核心优化技术详解

目录 前言 一、vLLM简介&#xff1a;为什么它如此重要&#xff1f; 二、核心技术一&#xff1a;PagedAttention — 显存管理的革命 2.1 传统注意力缓存的缺陷 2.2 分页式存储管理 三、核心技术二&#xff1a;张量并行 — 多GPU推理的基石 3.1 什么是张量并行&#xff1f…

MySQL 高级主题:索引优化、ORM 与数据库迁移

第五部分&#xff1a;索引优化1. 为什么需要索引&#xff1f;索引是提高数据库查询性能的关键数据结构&#xff0c;它类似于书籍的目录&#xff0c;可以帮助数据库快速定位到所需数据&#xff0c;而不必扫描整个表。2. 索引类型主键索引 (PRIMARY KEY): 唯一且非空&#xff0c;…

Eplan教程:网络与PLC

欢迎大家来到“Eplan带你做项目”第六个过程。在第五个过程中&#xff0c;Eplan基于实际项目的绘制&#xff08;电气设计中的电源回路以及电源分配相关回路&#xff09;重点分享分了“电机的供电和控制图纸的绘制”。本文中&#xff0c;先猜个问题&#xff0c;设计一个PLC系统&…

大模型落地全攻略:从技术实现到场景应用

大语言模型&#xff08;LLM&#xff09;的快速发展正在重塑各行各业的智能化进程&#xff0c;但其落地应用仍面临技术适配、场景融合、成本控制等多重挑战。本文将系统解析大模型落地的四大核心方向 ——微调技术、提示词工程、多模态应用和企业级解决方案&#xff0c;通过代码…

【论文】Zotero文献管理

Zotero文献管理 写论文前查找阅读大量文献&#xff0c;写论文时引用文献&#xff0c;都是一件非常麻烦的事情&#xff0c;一款合适的文献管理工具可以帮助我们更快捷地完成这些任务。zotero作为一款免费开源的工具&#xff0c;可以实现文献阅读、同步管理以及引用管理。 安装…

MsSQL 函数,实现数字转换成人民币大写

MsSQL 函数&#xff0c;实现数字转换成人民币大写-- 如果函数已存在则删除 IF OBJECT_ID(dbo.ConvertToRMBChineseNew, FN) IS NOT NULLDROP FUNCTION dbo.ConvertToRMBChineseNew GOCREATE FUNCTION dbo.ConvertToRMBChineseNew (NumberInput SQL_VARIANT -- 使用 SQL_VARIANT…

OpenHarmony深度定制:从系统到模块的全景剖析与自定义模块实战

摘要:OpenHarmony 作为面向万物互联时代的开源操作系统,其“系统-子系统-部件-模块”的四层架构设计,为开发者提供了高度可裁剪、可扩展的能力。本文将系统梳理这四层结构的职责边界与协作关系,并手把手演示如何向 OpenHarmony 新增一个可交付的自定义模块(Module),帮助…

数字社会学是干什么的?数字社会学理论与数字社会学家唐兴通讲数字社会学书籍有哪些?AI社会学人工智能社会学理论框架

在当今社会&#xff0c;传统物理空间和人际关系网络成为了许多年轻人寻找合适伴侣的重大障碍。以深圳为例&#xff0c;这座移民城市的大部分居民都来自外地&#xff0c;年轻人的人脉关系、尤其是亲戚关系大多仍在家乡。这使得深圳的单身男女在交友和婚恋方面的选择面变得狭窄&a…

数据库-MYSQL配置下载

目录 一.数据库概念 一、数据库的基本定义 二、数据库管理系统&#xff08;DBMS&#xff09; 三、数据库系统&#xff08;DBS&#xff09; 四、数据模型 五、数据库的特点 六、数据库的应用领域 二.MySql 一、开源免费&#xff0c;降低中大型项目成本 二、跨平台与兼容…

Java 中表示数据集的常用集合类

Java 中表示数据集的常用集合类 Java 集合框架提供了多种数据结构来表示和操作数据集&#xff0c;每种集合类都有其特定的用途和性能特征。以下是主要的集合类及其特点&#xff1a; 一、List 接口及其实现类 1. ArrayList 特点&#xff1a;基于动态数组实现优点&#xff1a;随机…

Django REST框架核心:GenericAPIView详解

Django REST framework (DRF) 中 GenericAPIView 的源码核心部分。 它是所有“泛型视图”的基础类&#xff0c;比如常用的 ListAPIView、RetrieveAPIView、CreateAPIView 都是继承自它。&#x1f31f; 作用继承自 APIView&#xff0c;因此仍然是一个标准的 DRF 视图。提供了常用…

深入解析HashMap的存储机制:扰动函数、哈希计算与索引定位

今天复习了一下HashMap的部分&#xff0c;写一篇博客记录一下今天学习内容虽然之前学习过&#xff0c;但由于后来没怎么使用过而且也没复习基本忘得差不多了在Java的HashMap中&#xff0c;高效存储键值对的核心在于哈希算法和索引定位。本文将结合源码逐步拆解存储流程&#xf…

【机器学习 / 深度学习】基础教程

阶段一&#xff1a;机器学习 / 深度学习基础教程定位&#xff1a;针对准备进入 AI多智能体开发 的初学者&#xff0c;打牢机器学习与深度学习的基础。一、为什么需要学习机器学习/深度学习 在进入智能体&#xff08;Agent&#xff09;开发之前&#xff0c;必须具备一定的 机器学…

ESP32应用——HTTP client(ESP-IDF框架)

目录 一、前言 二、URL 2.1 URL简介 2.2 URL示例 三、HTTP 3.1 HTTP协议概述 3.2 HTTP的工作原理 3.2.1 HTTP 请求-响应流程 3.2.2 HTTP 请求结构 3.2.3 HTTP请求方法 3.2.4 HTTP响应结构 3.2.5 HTTP状态码 四、ESP HTTP 客户端流程 五、ESP HTTP 客户端实战解析…

动学学深度学习07-现代卷积神经网络

动学学深度学习pytorch 参考地址&#xff1a;https://zh.d2l.ai/ 文章目录动学学深度学习pytorch1-第07章-现代卷积神经网络1. AlexNet1.1 AlexNet 的核心贡献是什么&#xff1f;1.2 AlexNet 与 LeNet 的主要区别有哪些&#xff1f;1.3 为什么 AlexNet 需要 GPU 训练&#xff1…