AliOS-Things在STM32上的堆内存管理:从内存布局到碎片化实战
1. 从一次内存告警说起为什么堆管理值得单独开一篇第一次在STM32上跑AliOS-Things的时候我遇到过一个很典型的现象设备连续运行十几个小时之后系统开始变得迟钝任务切换的响应时间从几毫秒涨到几十毫秒最后干脆卡死。用调试器挂上去一看栈没溢出任务优先级也没问题问题出在堆上——碎片化把一块本来够用的内存切得七零八落申请一个大一点的块直接失败而失败的那条路径又没有做好兜底整个系统就僵住了。这件事让我意识到很多人玩RTOS的时候注意力都放在任务调度、信号量、消息队列这些看得见的机制上堆内存管理往往被当成一个黑盒反正有malloc和free能用就行。但在资源受限的MCU上堆恰恰是最容易出问题、也最考验功底的地方。AliOS-Things作为一套面向物联网场景的轻量级操作系统它在堆管理上做了不少针对性的设计尤其是结合STM32这类Cortex-M平台内存布局、分配算法、碎片控制都有讲究。这篇内容就是围绕AliOS-Things在STM32上的堆内存管理展开的。我会从内存布局讲起把堆在整个RAM里处于什么位置、和栈怎么划分边界说清楚然后拆解AliOS-Things的堆管理模块到底提供了哪些接口、底层用了什么分配策略接着重点聊碎片化这个绕不开的坑以及在实际项目里怎么观测、怎么缓解最后给出一些我在真实调试中总结出来的参数配置和排查手法。适合已经能把AliOS-Things跑起来、但还没认真研究过内存管理的朋友也适合那些被跑一段时间就挂折磨过的同行。需要提前说明的是堆管理这个话题展开来内容很多这一篇主要聚焦在机制理解和观测手段上至于更深入的自定义分配器实现、内存池与堆的配合使用我会放在后续内容里单独讲。先把地基打牢后面才不至于空中楼阁。2. STM32的RAM里堆到底站在哪个位置2.1 从链接脚本看内存分区要理解堆管理第一步得搞清楚堆在物理内存里的位置。STM32的RAM布局不是操作系统随便定的而是由链接脚本linker script和启动文件共同决定的。以常见的Cortex-M系列为例一片SRAM通常被划分为几个区域.data段放已初始化的全局变量.bss段放未初始化的全局变量这两块在启动时由启动代码搬运或清零栈stack一般从RAM的高地址向下生长堆heap则从.bss段结束的位置向上生长。在AliOS-Things的工程里链接脚本通常会把堆的起始符号定义成类似__heap_start、结束符号定义成__heap_end这样的形式。系统启动后堆管理模块就拿这两个符号之间的空间作为自己的地盘。这里有个容易被忽略的点栈和堆是相向生长的如果两边都涨得太猛就会撞在一起也就是所谓的栈堆冲突。裸机开发时这个问题不明显因为栈用得少但一旦上了RTOS每个任务都有自己的栈主栈加上一堆任务栈再加上堆的消耗RAM很快就紧张了。我在一个项目里就吃过这个亏任务栈开得比较大方每个2KB开了8个任务光栈就吃掉16KB堆只剩几KB结果动态创建个稍大的缓冲区就失败。后来把任务栈压到1KB堆的空间立刻宽裕了不少。所以理解堆的位置本质上是在理解整个RAM的预算分配。2.2 堆与栈的边界一个动态的博弈栈和堆的边界不是固定的它随着程序运行不断变化。栈指针SP随着函数调用和中断不断移动堆指针则随着分配和释放上下浮动。AliOS-Things在初始化堆的时候会把堆的起始地址设在.bss段之后并且记录一个heap_end作为当前堆顶。每次分配堆顶向上移动释放的时候如果释放的是堆顶那块堆顶还会回退。这种设计的好处是内存利用率高堆能一直用到栈的脚下。但风险也在这里一旦堆顶逼近栈底就可能覆盖栈数据而这种覆盖往往是静默的不会立刻报错等到某个函数返回时才发现返回地址被改了程序跑飞到莫名其妙的地方。我在调试时养成了一个习惯在堆和栈之间留一段警戒区比如在链接脚本里预留几百字节的gap或者在初始化时把这段区域填上特定模式比如0xDEADBEEF运行一段时间后检查这个模式有没有被破坏就能提前发现栈堆冲突的苗头。提示栈堆冲突是嵌入式里最隐蔽的bug之一表现往往是随机的、难以复现的。预留警戒区并定期检查是成本最低的预防手段。2.3 多块RAM的处理有些STM32型号有多块RAM比如一块SRAM1加一块SRAM2或者带CCM RAM。CCM RAM的特点是只能被CPU访问DMA访问不了但速度快、不占总线。AliOS-Things的堆管理默认可能只认主RAM如果你想把堆放到CCM RAM上需要手动调整堆的起始和结束符号或者在初始化时指定区域。我一般会把频繁访问、不需要DMA的数据结构放到CCM RAM的堆里比如任务间传递的小消息、算法中间变量而DMA缓冲区则老老实实放在主RAM。这样既利用了CCM的速度又避免了DMA访问不到导致的数据错误。具体做法是在链接脚本里为CCM RAM单独定义一段heap区域然后在应用层用自定义的分配接口去管理它和系统默认堆分开。这个思路在后面讲内存池的时候还会展开。3. AliOS-Things堆管理模块的接口与底层逻辑3.1 对外暴露的分配接口AliOS-Things的堆管理对外主要提供几个接口最常用的是aos_malloc、aos_free、aos_calloc、aos_realloc这几个命名上对标标准C库但底层实现是独立的不依赖newlib的malloc。这样做的好处是可控标准库的malloc在不同工具链下行为不一致有的还带锁、带额外的元数据开销在MCU上不划算。AliOS-Things自己实现一套能针对小内存场景做优化。除了这几个基础接口还有aos_zalloc分配并清零以及一些带对齐参数的变体。带对齐的分配在DMA场景下很有用因为很多STM32的外设DMA要求缓冲区地址按4字节或32字节对齐。如果直接用aos_malloc拿到一个不对齐的地址再手动对齐就会浪费前面的空间而且free的时候还得还原原始指针很麻烦。用对齐分配接口一步到位省心。这里有个细节值得说aos_realloc在堆上的行为。它会尝试在原地扩展如果后面空间不够就新分配一块、拷贝数据、释放旧的。在碎片化严重的时候realloc很容易失败因为它要求的是一块连续空间。我在处理动态增长的缓冲区时更倾向于预分配一个足够大的块或者用链表把多个小块串起来而不是频繁realloc。3.2 底层分配算法首次适配与分离适配AliOS-Things的堆管理底层早期版本用的是一种带合并的首次适配first-fit算法。简单说堆被组织成一个空闲块链表每块记录自己的大小和状态。分配时从头遍历找到第一块足够大的空闲块切一块出来剩下的如果还够大就继续留在链表里。释放时检查相邻块是否空闲如果是就合并减少碎片。首次适配的优点是实现简单、分配速度快尤其是小块缺点是容易在链表头部留下很多小碎片导致后面的大块分配变慢。后来一些版本引入了分离适配segregated fit的思想把空闲块按大小分到不同的桶里小请求去小桶找大请求去大桶找减少了遍历长度。这个改进在频繁分配释放小块比如消息队列的节点时效果明显。我用逻辑分析仪抓过分配耗时在碎片化程度中等的情况下首次适配分配一个32字节的块大概几微秒分离适配能压到一两微秒。别小看这几微秒在中断上下文里做分配虽然不推荐或者高频消息处理时累积起来就是可观的CPU占用。3.3 元数据开销每个块都背着小书包任何堆分配器都要在每块内存上附加元数据记录这块多大、是否空闲、前后块在哪。AliOS-Things的元数据通常是一个结构体包含块大小、状态标志、以及指向前后空闲块的指针如果用了双向链表。在32位平台上这个结构体少说8字节多则16字节。这意味着你申请1字节实际消耗可能是17字节甚至更多。在小内存场景下这个开销比例很吓人。我见过一个项目为了省事用aos_malloc分配大量16字节的小结构结果元数据开销比数据本身还大RAM很快见底。后来改成内存池每个块只留一个字节的状态位开销降到几乎可以忽略。所以选分配策略的时候一定要把元数据算进去。如果应用里小块分配特别多堆不是最优解内存池才是。堆更适合大小不一、生命周期不规则的分配。分配方式元数据开销适用场景碎片风险系统堆每块8-16字节大小不一、低频分配中高内存池每块1-4字节固定大小、高频分配极低静态数组无数量固定、编译期可知无4. 碎片化那个让设备跑着跑着就挂的元凶4.1 碎片是怎么产生的碎片化分两种内部碎片和外部碎片。内部碎片是分配出去的块比实际需要的大多出来的部分浪费了比如你要10字节分配器给你16字节的块那6字节就是内部碎片。外部碎片是空闲内存总量够但被切得太散凑不出一块连续的大空间。在AliOS-Things的堆上外部碎片是主要矛盾。想象一下你先分配A100字节、B50字节、C100字节然后释放B此时中间空出50字节。接着你想分配一个80字节的块虽然总空闲有50字节加上堆顶可能还有空间但中间那50字节不够如果堆顶空间也不够分配就失败。这就是外部碎片导致的明明有内存却用不了。更麻烦的是碎片化是渐进式的。程序刚启动时内存整整齐齐跑几小时后碎片率可能就到30%以上。而且碎片化程度和分配模式强相关如果分配释放的大小和顺序有规律碎片可控如果随机碎片会迅速累积。4.2 用数据说话碎片率怎么算、怎么观测光凭感觉说碎片严重没用得有量化指标。我常用的两个指标是空闲块数量和最大空闲块大小。理想情况下空闲内存应该是一整块如果空闲总量10KB但最大空闲块只有2KB说明碎片很严重。AliOS-Things提供了一些堆统计接口可以拿到总大小、已用大小、空闲大小、最大空闲块等信息。我在调试时会在一个低优先级任务里定期打印这些数据观察趋势。如果发现最大空闲块持续下降而空闲总量没怎么变那就是碎片在累积。还有一种更直观的方法在堆上画内存地图。把堆按固定粒度比如64字节划分每个粒度标记为空闲或占用定期dump出来。这样能一眼看出碎片分布。我写过一个简单的可视化脚本把dump数据转成字符图占用是#空闲是.跑一段时间后对比碎片的变化一目了然。提示不要等到出问题才看堆统计。在开发阶段就养成定期打印的习惯把碎片率作为一项健康指标监控。4.3 缓解碎片的几个实用手段完全消除碎片不现实但可以缓解。第一个手段是分配大小归类把常用的分配大小固定成几档比如32、64、128、256字节所有分配都向上取整到最近的档。这样释放后的块更容易被复用因为大小一致。代价是内部碎片增加但外部碎片减少总体往往更划算。第二个手段是延迟释放批量整理。对于生命周期短、频繁分配释放的对象不要立即free而是先放到一个待回收列表等积累到一定数量或者系统空闲时统一释放。这样能减少堆的频繁变动给合并创造机会。第三个手段是关键大块预分配。系统里那些必须连续的大缓冲区比如显示framebuffer、音频缓冲在启动时就一次性分配好之后不再动。剩下的堆留给小对象折腾即使碎片化也不影响关键功能。我在一个音频项目里就是这么干的启动时先把DMA用的双缓冲每块4KB分配好锁定不动运行时的消息、状态对象都走内存池堆只用来处理一些临时的、大小不定的字符串拼接。这样跑了一周堆的最大空闲块基本稳定没有出现衰减。5. 在STM32上配置和调试堆的实操细节5.1 堆大小的确定别拍脑袋堆开多大很多人是拍脑袋定的看着RAM还剩不少就随手写个#define HEAP_SIZE (16*1024)。这样要么浪费要么不够。合理的做法是先估算再实测最后留余量。估算的方法是列出所有走堆分配的对象算它们的峰值总和。比如消息队列节点最多同时存在20个每个64字节那就是1280字节动态字符串缓冲区峰值8KB其他零散分配算2KB。加起来约11KB那堆至少开12KB再留30%余量开16KB比较稳妥。实测的方法是在堆统计里记录历史峰值。AliOS-Things的堆模块一般会记录max_used这样的字段跑完一轮完整的业务流程后读出来就是实际峰值。我习惯在压力测试下跑比如让设备连续处理消息、反复创建销毁任务把峰值逼出来。余量留多少有讲究。如果应用分配模式很规律20%够如果分配随机、生命周期长建议50%。因为碎片会让可用内存打折扣余量不足时即使总空闲够也可能分配失败。5.2 对齐与DMA那些容易翻车的地方STM32的DMA对地址对齐有要求不同外设要求不同有的要求4字节对齐有的要求字对齐SDIO、以太网这类可能要求32字节对齐。如果用堆分配DMA缓冲区一定要用带对齐参数的接口或者手动保证。我踩过一个坑用aos_malloc分配了一个以太网接收缓冲地址是4字节对齐的但以太网DMA要求32字节对齐结果DMA传输时数据错位收到的包全是乱的。查了半天才定位到对齐问题。后来改成对齐分配一次搞定。还有一个坑是cache。带cache的STM32比如H7系列上DMA和CPU访问同一块内存时cache一致性要处理好。堆分配的内存默认可能是cacheable的DMA写入后CPU读到的是cache里的旧数据。解决办法是把DMA缓冲区放到non-cacheable区域或者在DMA传输前后做cache维护操作。这个和堆管理本身关系不大但用堆分配DMA缓冲时绕不开必须心里有数。5.3 分配失败的兜底策略堆分配失败是常态不是异常。关键是要有兜底。最忌讳的是ptr aos_malloc(size); memcpy(ptr, ...)这种写法ptr为NULL时直接跑飞。我的做法是封装一层分配函数失败时记录日志、返回错误码调用方必须处理。对于关键路径还要有降级方案比如消息分配失败时丢弃低优先级消息而不是崩溃缓冲区分配失败时用静态的小缓冲顶上保证基本功能。另外分配失败后不要立刻重试尤其是在中断或高频循环里。失败往往意味着内存紧张立刻重试只会加剧。合理的做法是设置一个退避时间或者触发内存回收如果有的话等条件改善再试。void *safe_malloc(size_t size) { void *p aos_malloc(size); if (p NULL) { LOGE(heap, alloc %u failed, free%u, max_free%u, size, aos_get_free_size(), aos_get_max_free_size()); /* 触发降级逻辑或告警 */ } return p; }这段代码看着简单但把失败时的关键信息打出来排查问题时能省很多事。我靠这几行日志定位过好几次碎片问题。6. 几个真实调试场景的复盘6.1 场景一任务创建失败根因在堆不在任务有个项目系统跑起来后创建第5个任务时失败返回错误码提示资源不足。第一反应是任务数量超限查了配置最大任务数设的是10没超。再查任务栈每个1KB5个才5KBRAM也够。最后打印堆统计发现空闲只剩几百字节——原来前面几个任务在初始化时各自分配了不少堆内存把堆吃光了。这个案例的教训是任务创建本身也要从堆上分配任务控制块TCB如果堆不够任务就创建不了。排查资源问题时不能只看单一资源要把堆、栈、任务数、信号量数等一起看。后来我把初始化阶段的分配改成静态数组堆压力立刻缓解。6.2 场景二长时间运行后响应变慢前面提到的那个跑十几小时变慢的案例根因是碎片化。具体过程是系统里有个日志模块每次记录都malloc一块写完后free。日志大小不定从几十字节到几百字节。跑久了堆被切得粉碎每次分配都要遍历很长的空闲链表耗时增加同时大块分配开始失败日志模块进入重试循环进一步拖慢系统。解决办法有两个一是把日志缓冲改成环形缓冲区静态分配彻底不走堆二是给日志分配加大小分档减少碎片。我选了第一个因为日志本来就是顺序写入、顺序读取的场景环形缓冲完美契合。改完后连续跑一周响应时间稳定。6.3 场景三realloc引发的隐蔽bug有个同事的代码里用了aos_realloc来动态扩展一个配置缓冲区。大部分时候没问题但偶尔配置项多的时候realloc返回新地址他忘了更新所有指向旧地址的指针导致部分代码还在用已经free的旧指针数据错乱。这种bug很难查因为出错的地方和realloc的地方可能隔很远。后来我们约定凡是realloc必须用返回值更新指针并且检查所有别名。更好的做法是干脆不用realloc改成预分配足够大的空间或者用链表。realloc在嵌入式里是个危险动作能不用就不用。7. 堆管理进阶什么时候该换内存池聊到这里你应该能感觉到堆很灵活但灵活是有代价的——碎片、元数据开销、分配耗时不确定。当应用里出现固定大小、高频分配释放的模式时堆就不是最优解了内存池更合适。内存池的思路很简单启动时一次性分配一大块切成等大的小块用一个空闲链表串起来。分配就是从链表头摘一个释放就是挂回链表头。O(1)复杂度无碎片元数据开销极小每块一个指针或一个状态位。缺点是只能分配固定大小且启动时就占用了全部内存。AliOS-Things本身也提供了内存池相关的组件可以和堆配合使用。我的经验是把系统里那些数量可预测、大小固定的对象都迁到内存池比如消息节点、网络包缓冲、传感器数据结构堆只留给真正动态、大小不定的场景。这样双管齐下既保证了关键路径的确定性又保留了灵活性。判断标准可以总结成一句话如果一个对象的分配大小在编译期或启动期就能确定且分配频率高就用内存池否则用堆。按这个标准梳理一遍代码往往能砍掉一大半堆分配系统稳定性立竿见影地提升。至于内存池的具体实现、如何和AliOS-Things的组件对接、以及多级内存池的设计内容比较多我打算放在下一篇里详细展开。这一篇先把堆的机制、观测、配置和避坑讲透把基础打扎实。毕竟只有真正理解了堆的脾气才知道什么时候该请内存池出场。最后分享一个我个人的小习惯每次项目进入联调阶段我都会在系统里挂一个内存健康任务每隔一段时间打印堆的空闲量、最大空闲块、碎片率以及内存池的使用率。这些数据攒下来不仅能发现当前问题还能为下一个项目的内存预算提供参考。嵌入式开发里内存从来不是够用就行而是要心里有数。

相关新闻

工业控制上位机选型:Qt在2026年的架构设计与实战避坑指南

工业控制上位机选型:Qt在2026年的架构设计与实战避坑指南

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 3:03:44 阅读更多 →
汽车信息安全工程师:从硬件可信根到云安全的全栈能力图谱

汽车信息安全工程师:从硬件可信根到云安全的全栈能力图谱

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/13 3:02:43 阅读更多 →
conda虚拟环境原理:为什么能创建不同Python版本而venv不能?

conda虚拟环境原理:为什么能创建不同Python版本而venv不能?

很多人第一次被“虚拟环境”这个概念搞晕,往往都是从这个问题开始的:我已经用 venv 建好了一个环境,为什么python --version还显示系统自带那个版本?更奇怪的是,别人在教程里写一句conda create -n py311 python3.11&a…

2026/10/13 3:02:43 阅读更多 →

最新新闻

2026年网络安全转行全解析:岗位供需、薪资真相与实战路径

2026年网络安全转行全解析:岗位供需、薪资真相与实战路径

“现在转网安还来得及吗?”“听说2026年缺口300万,是真的吗?”“35岁转行会不会太晚?”——2026年了,这些问题依然在各大社区被反复刷屏。我做了近十年安全工作,从乙方驻场干到甲方安全负责人,也…

2026/10/13 3:47:55 阅读更多 →
Windows文件夹被占用无法删除?用句柄机制和Process Explorer五分钟定位真凶

Windows文件夹被占用无法删除?用句柄机制和Process Explorer五分钟定位真凶

遇到这种问题真的烦:右键删除一个文件夹,Windows 弹出一句“操作无法完成,因为文件夹已在另一个程序中打开”,英文环境就是 Unable to delete / Unable to rename。文件夹就那么杵在屏幕上,删不掉也改不了名&#xff0…

2026/10/13 3:47:55 阅读更多 →
从命令行到图形界面:VS Code CMake Tools配置C++项目全攻略

从命令行到图形界面:VS Code CMake Tools配置C++项目全攻略

每次要在命令行里敲cmake -S . -B build -DCMAKE_BUILD_TYPEDebug,再敲cmake --build build --config Debug,然后才敢打开VS Code里写代码——这种状态我持续了挺长时间。直到我把配置切到VS Code的CMake Tools扩展上,情况才彻底变了。这篇指…

2026/10/13 3:47:55 阅读更多 →
MSCMCCHS.DLL丢失别乱下!用系统工具修复与安全补充指南

MSCMCCHS.DLL丢失别乱下!用系统工具修复与安全补充指南

很多朋友在使用 Windows 系统的过程中,都遇到过弹窗提示“MSCMCCHS.DLL文件丢失”或者“找不到MSCMCCHS.DLL”的情况。这玩意儿一出现,往往某个软件就打不开了,甚至开个游戏、跑个设计工具都要罢工。好多人第一反应就是上网搜“免费下载”&am…

2026/10/13 3:47:55 阅读更多 →
合肥功能区SHP数据获取与GIS分析全流程指南

合肥功能区SHP数据获取与GIS分析全流程指南

简介:本资源为合肥市功能区空间划分的GIS矢量数据集,面向城市规划师、地理信息专业学生、区域研究学者及政府规划部门技术人员,用于支撑城市功能分析、空间政策评估、多源数据叠加建模等实际工作。数据以标准SHAPEfile格式组织,共…

2026/10/13 3:47:55 阅读更多 →
SpringBoot+Vue美食网站毕设项目:从数据库设计到前后端部署全解析

SpringBoot+Vue美食网站毕设项目:从数据库设计到前后端部署全解析

SpringBoot 加 Vue 的 B/S 架构美食网站,这类项目在 Java Web 毕设里算是出场率相当高的一个选题。不管是刚学完 SSM 想找个完整项目练手,还是做毕设需要一套能跑通、能讲清楚、能答辩的成品,这套组合都很有代表性。我自己前后帮人看过的、动…

2026/10/13 3:46:55 阅读更多 →

日新闻

物联网系统集成避坑指南:从选型到验收的关键要点

物联网系统集成避坑指南:从选型到验收的关键要点

做了这么多年物联网系统集成的项目,我最大的感受是,大部分坑不是出在技术前沿,而是出在一些看起来很平常的地方。设备选了便宜的、协议没问清楚、现场没摸透、验收标准写得含糊——这些细枝末节,最后都会变成延期、超支和扯皮的大…

2026/10/13 0:00:57 阅读更多 →
ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

ESP32舵机控制全攻略:从PWM原理到高级玩法与常见故障排查

如果你玩ESP32有一阵子了,很难不碰到舵机控制这道坎。做智能小车要转方向,做机械臂要抬关节,做云台要偏航俯仰,背后都是同一个东西在干活:舵机。而我见过太多人卡在“代码能编译、舵机就是不听话”这个阶段&#xff0c…

2026/10/13 0:00:57 阅读更多 →
CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

CAN总线原理与STM32实战:抗干扰、仲裁、错误处理全解析

1. 为什么CAN总线至今仍是工业现场的“硬通货”?——从汽车底盘到智能温室的真实需求你有没有拆过一辆老款燃油车的中控台?或者调试过某高校实验室里那台跑着Modbus协议却频频丢帧的PLC控制柜?又或者,在某个农业物联网项目里&…

2026/10/13 0:00:57 阅读更多 →

周新闻

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

流感时间序列预测实战:ARIMA/LSTM全流程拆解与避坑指南

简介:基于 ARIMA、LSTM、Transformer 等模型的流感时间序列预测 Python 源码,面向计算机相关专业课程设计与期末大作业学生,以及项目实战学习者。内容覆盖预处理、平稳性检验、定阶、残差分析、多模型对比预测的完整时序建模流程,…

2026/10/13 2:54:56 阅读更多 →
影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别

影刀RPA新手教程:键盘模拟输入实战——输入文本与模拟按键的区别 做影刀RPA自动化,十个新手有八个栽在"往输入框里填东西"这件事上:要么填不进去,要么填了一半,要么直接把原来内容追加在后面。这背后的根因&…

2026/10/12 0:16:38 阅读更多 →
影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容

影刀RPA新手教程:阅文起点小说数据采集实战——书籍信息与章节内容 1. 认识影刀:什么场景该用RPA采小说数据 起点中文网的页面结构相对稳定——分类榜单、书籍详情、章节内容三块独立页面,跳转链路清晰。这种场景非常适合影刀自动化&#x…

2026/10/13 1:58:08 阅读更多 →

月新闻

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

我发现了一个新思路:用 Remotion + Claude Code 像写代码一样自动化生成短视频

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 21:05:09 阅读更多 →
Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

Windows下 Codex 中 Chrome 和 Computer Use 插件不可用问题排查及解决参考方式:TaoToken 统一 Key 配置与验证

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 14:48:49 阅读更多 →
黑夜航拍船只数据集训练YOLOV5模型全流程解析

黑夜航拍船只数据集训练YOLOV5模型全流程解析

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

2026/10/12 18:11:17 阅读更多 →