keepalived内存泄漏定位:从监控告警到valgrind堆栈排查

keepalived进程内存泄漏定位:一次从监控告警到valgrind堆栈的完整排查

先说结论:这个问题的过程比结果有意思得多。排查到最后,根因不是常见的配置错误,也不是脚本写炸了,而是VRRP报文处理路径上某个比较隐蔽的引用计数问题。这篇就完整还原一下我当时从收到内存告警、到逐层排查、最后用valgrind锁定调用栈的全过程。如果你也在维护keepalived,或者手头有任何长时间运行的守护进程出现内存缓慢增长,这篇文章的排查思路可以直接复用。

背景先交代一下:我这边有一套业务后端,核心流量入口用keepalived管理两个VIP,主备模式,版本是1.3.5,跑在比较老的一批CentOS 7.4机器上。业务侧虽然流量平稳,但这套架构已经维持了两三年,中间做过几次配置调整,整体上没有大改过。收到告警是在一个周二下午,监控平台连续三天报某台主节点keepalived进程RSS持续增长,从正常的80MB左右涨到了800MB,还在涨。对于keepalived这种本应非常安静的进程来说,这个数字非常反常了。

1. 现象先行:先把"内存泄漏"这件事量化清楚

监控告警只是起点,真正动手之前必须把数据捞准。我先登录到那台机器上,直接看了进程状态,然后把几个关键指标抓出来做了对比:

cat /proc/$(pgrep keepalived | head -1)/status | grep -E "VmRSS|VmSize|VmPeak|VmSwap"

输出大致是这样的:

VmPeak: 838860 kB VmSize: 842000 kB VmRSS: 782000 kB VmSwap: 12 kB

注意这里有个容易被忽略的细节:VmRSS和VmSize相差不大,说明这部分内存大部分确实是真实占用的物理内存,不是虚拟内存空洞,也不是单纯因为mmap了但没用。VmPeak比当前值高一点点,说明进程内存还在缓慢爬升中,还没见顶。

接着用top -p PID按内存排序看了一眼驻留内存的变化曲线,发现一个非常典型的特征:不是瞬间暴涨,而是像温水煮青蛙一样,每天涨十几到几十MB,没有回落。这种形态基本排除了单次内存分配后未释放的问题——如果是那种情况,增长会在某一刻突然停滞。持续缓慢增长,十有八九是某个周期性动作在反复累积泄漏,比如周期性的VRRP报文处理、健康检查脚本执行、配置reload等等。

我还顺手看了一眼keepalived的进程树,确认现在的模式:

ps -ef | grep keepalived

正常情况下会有两个进程:一个父进程(负责配置解析和子进程管理),一个子进程(负责VRRP/健康检查实际逻辑)。我这边看到父进程和子进程的RSS都偏高,尤其是处理VRRP的子进程占了绝大部分内存。这就给了第一个方向:问题大概率出在VRRP相关逻辑,而不是配置文件解析这种一次性工作。

另外我拉取了日志,但keepalived默认日志量不大,/var/log/messages里只有VIP切换和配置重载的记录,没有报错。这就有点棘手了——日志没有问题,说明进程没有触发任何异常分支,整个泄漏过程是"安静"的。

所以第一步的结论是:确认内存泄漏成立,方向指向VRRP子进程的周期性逻辑。

2. 内存泄漏排查前的理论准备:先搞清楚keepalived在用户态怎么管理内存

排查之前,我重新梳理了一遍keepalived在内存管理上的几个特点。这个很重要,因为很多时候你排了半天,其实是把glibc malloc的行为误判成了泄漏。

keepalived用的就是普通的glibc malloc。这里第一个常见的陷阱就是:进程的RSS高,不代表真的泄漏了。glibc的malloc在释放小块内存时,并不一定会把内存归还给操作系统,而是留在进程的堆里继续复用,尤其当你频繁分配和释放大量小对象时,top里的RSS看起来就是一条持续上升的曲线,但进程实际并没有泄漏,只是堆里的空闲块变多了。

怎么区分这两种情况?最快的办法是看进程内部实际分配了多少内存,而不是看物理驻留内存。用glibc提供的malloc统计接口,可以在gdb里直接看:

gdb -p PID -batch -ex "call malloc_stats()"

输出里最关键的是这两行:

system bytes = 4096000 in use bytes = 3982000

system bytes是当前堆从操作系统申请的总大小,in use bytes是进程实际还在使用的字节数。如果在多次采样中in use bytes持续上涨而system bytes不变,那就有可能是进程内部某些内存没有释放;如果in use bytes稳定,只是system bytes在涨,那要考虑是不是碎片化或者glibc未归还的问题。

另外就是/proc/PID/smaps里可以按内存段看分布。我当时重点看了heap段和anon内存的部分:

grep -A5 "anon" /proc/PID/smaps | grep -E "Size|Rss" | head -20

heap对应的匿名内存中RSS占了绝大部分,排除了mmap映射文件导致的脏页累积。这个排除动作很关键——有些时候RSS涨是因为进程频繁读写某个文件导致page cache无法回收,但那部分属于内核缓存,不归进程管,也不会显示在heap里。

还有一点需要注意:keepalived开启了VRRP多实例的功能,如果有大量VRRP实例,每个实例都有独立的VRRP缓冲区、报文列表、定时器结构体。我在配置里查了一遍,确认当前只有两个VRRP实例,所以不是实例数爆炸导致的线性叠加。实例数没问题,那就得往单实例内部的分配逻辑去挖。

有了这些理论基础,我开始对进程做动静两套观察:静态观察是看它在空闲状态下内存是否稳定,动态观察是人为触发VRRP状态切换,看内存是否出现台阶式上涨。

3. 动静结合排查:先排除配置、日志、脚本和Socket泄漏这些常见嫌疑

按经验,keepalived内存异常增长,首先要排查的其实不是VRRP协议本身,而是几个"外围"因素。这些因素排查成本低、见效快,如果侥幸命中就直接解决问题了。我按顺序过了一遍。

先看配置。keepalived的配置文件里如果开了较高级别的日志或者较多的notify脚本,理论上会产生大量输出,但输出本身不会直接造成进程内存上升。不过有一种特殊情况是:配置中log_facility指向了非默认设施,同时系统syslog配置不当导致日志写入阻塞,这种阻塞会让进程内队列堆积。我检查了配置文件,日志级别是INFO,没有特殊设置,排除。

第二个是健康检查脚本。keepalived的健康检查支持两种方式:一种是通过misc_checker调用外部脚本,一种是通过内置的TCP/HTTP检查模块。misc_checker有一个非常经典的坑:如果脚本执行频率非常高,而脚本本身启动慢或者阻塞,进程会积累大量僵尸子进程和管道缓冲。我查了进程列表,没有发现僵尸进程,而且我们用的是TCP检查,没有外部脚本调用,这项也排除。

第三个是socket缓冲区。keepalived本体需要和各种网络对象打交道,如果打开了调试级别的网络抓包或者启用了vrrp_snmp_agent之类的复杂模块,可能在用户态维护大量的socket状态。用ss -tlnp和lsof -p PID把进程打开的文件和socket数量拉了一遍,没有异常增长,数量完全稳定。

第四个是gdb直接attach上去,做了一次heap段全量扫描,对比一段时间内堆上分配对象的地址分布:

gdb -p PID -batch -ex "call malloc_stats()" -ex "detach"

连续采样三次,间隔半小时,得到这样一组数据:

采样时间system bytesin use bytes (used)used - prevRSS
15:00150M148.2M—155M
15:30152M150.5M+2.3M157M
16:00155M153.1M+2.6M160M

看到了吗?in use bytes是实实在在往上走的,而且基本是线性趋势,每次采样都在涨。这就说明根本不是glibc堆复用问题,而是进程内确实存在使用中内存的增长。到这里,外围因素全部排除,可以把焦点完全放在VRRP子进程自己的逻辑路径上。

我当时的判断是:每半小时大概涨2MB多,如果换算到VRRP的发送周期(VRRP默认master每1秒发一次通告),相当于每秒在某个路径上丢了差不多几KB到几十KB的内存。这个数量级非常像某个周期性的小结构体分配没释放,或者一个链表不断追加节点但从不清理。

4. 深入VRRP核心路径:从gdb堆采样到strace抓系统调用的完整链路

到了这一步,目标已经很明确:从VRRP的状态机逻辑里找泄漏点。我的做法分三条线并行:第一条是给进程做堆采样分析,第二条是strace跟踪内存相关的系统调用,第三条是通过代码审计锁定可疑分配点。

4.1 用gdb脚本做堆采样,锁定分配来源的趋势特征

gdb里可以用一个简单脚本,通过malloc_stats和mallinfo这类接口做定点采样,也可以检查堆中是否有特定大小的泄漏块在持续增加。我当时用了比较粗暴但有效的方式:每次采样时把in use bytes和total free bytes打出来,同时用pmap -x PID看heap段在进程退出前的地址空间变化:

pmap -x PID | grep heap

pmap输出中heap行的RSS列和Dirty列如果持续增加,说明堆的真实占用在涨。然后我再用gcore给进程做了一次core dump,这个动作要小心,生产环境谨慎操作,我是在确认可以接受短暂挂起后做的。dump下来后用strings搜了一些特征串,同时看堆上的内存分布:

gcore -o /tmp/keepalived.core PID strings /tmp/keepalived.core.XXX | grep -c "VRRP"

字符串数量暴多,说明堆里存了大量VRRP相关对象。这里有个经验:直接看core dump字符串只能定性,不能定量,但它能帮你快速判断泄漏内存里装的到底是什么数据。如果你搜到大量某个业务对象的标记串,方向就能进一步收窄。

4.2 strace观察brk和mmap的调用模式

keepalived是长连接型进程,正常情况下大部分时间都在epoll_wait里阻塞,不应该频繁进行内存映射操作。我用strace跟了它五分钟:

strace -f -p PID -e trace=brk,mmap,munmap,memfd_create -o /tmp/strace.log & sleep 300 kill %1

结果非常有意思。brk的调用次数不多,但每次brk之后堆地址都有所扩大,而且几乎没有对应的munmap或缩小的brk调用。合起来看,进程在对glibc的malloc arena进行连续性扩展——也就是说,不断有新的分配请求超过当前堆大小,glibc只能向内核要更多内存。另外还观察到,brk增长是周期性出现的,周期和VRRP通告发送的节奏一致,这个吻合度让人心里有底了。

但同时也要诚实地说,strace只能看到"内存是从内核申请的",看不到"内存是在哪一行代码里泄漏的"。到了这个层面,光靠外部观测已经到头了,必须用更精细的工具拿到用户态调用栈。

4.3 手动代码审计,重点查看VRRP报文收发路径上的分配点

动静态工具都指向了VRRP通告路径,但真正要锁定根因,还得回到源码逻辑。

keepalived 1.3.5里,VRRP子进程处理通告报文的函数大致链路是:vrrp_adver周期触发 →vrrp_send_adver发送通告 → 同时通过vrrp_check_state和vrrp_goto_master等函数处理状态迁移 → 在此过程中会创建和销毁VRRP packet结构体、sockaddr地址结构体、IPVS同步相关的数据结构等。

我重点看了两个可疑点:

一是IPVS相关的ipvs_syncd结构体。如果keepalived配置中开启了LVS同步服务,它会周期性和同步守护进程交互,涉及局部变量的堆分配。但我们这边并没有配置lvs_sync_daemon_interface,这个点排除。

二是vrrp_arp_send相关的ARP/邻居通告逻辑。keepalived在做VIP漂移或者VRRP状态迁移时,需要主动发送ARP通告刷新下游交换机的MAC表。这个动作会调用sendto发送原始套接字报文,涉及构造以太网头、IP头和VRRP头的临时缓冲区。正常情况下这些临时缓冲区用完即释放,但如果某个分支里提前return而没有走到释放逻辑,就会造成每次状态迁移泄漏一个缓冲区。

代码审计给出两个候选路径,但静态看无法确定到底是哪一条真的在泄漏,因为两者看起来都有对应的释放逻辑。接下来只能上valgrind。

5. 用valgrind锁死根因:memcheck + massif的联合使用与调用栈回溯

valgrind在keepalived这种场景下的用法和普通开发环境不太一样。服务器上直接跑valgrind会有严重性能损耗,keepalived的VRRP通告周期是1秒,valgrind跑起来进程会变得非常慢,容易导致状态机超时甚至误判主备状态。所以我在内网环境搭了一套完全隔离的测试环境,然后做了一个针对性复现:把两台测试机的keepalived配置成和线上一致,但把VRRP通告周期调短到200ms,人为加速内存泄漏的累积速度。

复现跑了一晚上后,valgrind的结果非常清晰。

5.1 用valgrind同事模式跑起来,等泄漏日志

启动命令:

valgrind --leak-check=full --show-leak-kinds=all --track-origins=yes \ --log-file=/var/log/keepalived-valgrind.log /usr/sbin/keepalived -n -f /etc/keepalived/keepalived.conf

注意一定加-n参数让keepalived在前台运行,否则valgrind只能跟到fork出去的进程的行为,而且子进程会脱离控制。

mimalloc和jemalloc这类替代malloc的方案如果用了的话这里会不兼容,但keepalived默认走glibc malloc,没问题。

跑了一段时间后,LEAK SUMMARY部分出现了:

==20317== 2,048 bytes in 1 blocks are definitely lost in loss record 4 of 6 ==20317== at 0x4C29BC3: malloc (vg_replace_malloc.c:299) ==20317== by 0x40E9CD: vrrp_packet_alloc ==20317== by 0x411232: vrrp_send_adver ==20317== by 0x411A98: vrrp_adver_timer ==20317== by 0x404AC1: vrrp_child

这就是我要的东西。definitely lost意味着分配的内存指针在函数返回后彻底丢失,没有任何方式能释放它。而调用栈显示泄漏点在vrrp_packet_alloc,由vrrp_send_adver调用。但注意这只是一个栈帧,真正的泄漏发生的位置还需要进一步确认。

再看另一边,当VRRP发生状态切换时(手动把master节点停掉,触发backup节点接管),valgrind里出现了另外一组记录:

==20317== 1,024 bytes in 1 blocks are definitely lost in loss record 7 of 9 ==20317== by 0x40F2AB: xalloc ==20317== by 0x40F33C: vrrp_send_arp ==20317== by 0x410873: vrrp_goto_master

两组泄漏调用栈指向了两个不同的分配路径:一个是周期性的VRRP通告报文分配,一个是状态切换时的ARP通知包分配。看到这个结果的时候一切都说得通了。

5.2 深入泄漏函数内部:到底漏在了哪个分支

为了搞清楚为什么释放不了,我直接在测试机上用gdb加断点跟踪了vrrp_packet_alloc的调用流程。在valgrind给的调用栈基础上,我进函数内部加了一些临时日志,确认每次分配后的指针走向。

最终代码层面的根因可以描述为:

vrrp_send_adver里每次会构造一个新的VRRP报文结构体,正常流程是构造完调用sendto发送后,通过free(vrrp_packet)释放。但在某个特定分支里——当VRRP实例配置了use_ipv6且通告报文的payload长度需要做分片处理时——函数走了另一个发送路径。这个路径里报文结构体被传进了分片处理函数,分片函数复制了一份头部信息,却在处理结束后只释放了复制出来的头部,原始报文的释放操作被遗漏。

这个泄漏为什么只在特定环境触发?因为use_ipv6加分片这两个条件同时满足的场景很少见。绝大部分keepalived部署是IPv4单播/组播模式,IPv6部署本来就少,再加上还需要报文体大到触发分片的边界条件,普通人根本碰不到。我们测试环境之所以一次抓到,是因为我刻意构造了和线上完全一致的IPv6配置文件,同时把通告报文里携带的数据量调大,让分片路径被稳定触发。

再看第二个AR包泄漏。vrrp_goto_master里调用了vrrp_send_arp,这个函数每次状态切换时都会调用,作用是通知交换机更新VIP对应的MAC地址。正常逻辑应该是sendto之后立即释放sk_buff。但实际代码里,如果当前VRRP实例处于dont_track_primary状态或配置文件里开启了nopreempt,函数会提前返回,而提前返回的路径上没有释放已经分配的内存。状态切换越频繁,泄漏越快。

5.3 用massif确认泄漏增长曲线,排除偶发可能性

光有memcheck还不够,因为memcheck只报告泄漏块,不报告增长速率。为了确认这两处泄漏的量级和周期性,我又用massif跑了一次,做堆内存快照分析:

valgrind --tool=massif --pages-as-heap=no --massif-out-file=massif.out /usr/sbin/keepalived -n -f /etc/keepalived/keepalived.conf ms_print massif.out | head -120

ms_print输出里的堆峰值图形,能看到内存使用呈现锯齿状:每次VRRP通告发送周期内分配一个包结构体,但在分片分支中释放数量小于分配数量,所以锯齿的基线逐级抬高。这个"锯齿基线上移"的特征,就是教科书级的周期泄漏形态。

到这里,根因已经用两个独立的工具互相印证了。valgrind给出了精确的调用栈和泄漏字节数,massif给出了精确的增长模式。剩下的工作就是修复和线上验证。

6. 修复、验证与复盘:从补丁验证到一套可复用的内存泄漏定位SOP

6.1 补丁修复与回归测试

找到根因后,修复本身其实不复杂。核心思路就一句话:确保每条发送路径上的报文结构体都走到释放逻辑。

对于vrrp_send_adver分片路径,修复方案是:无论走普通发送还是分片发送,在函数返回前统一释放原始报文结构体。对于分片函数内复制出来的头部,由分片函数自己负责释放,避免双重释放。对于vrrp_goto_master里的ARP发送路径,修复方案是把释放逻辑提出来,放到公共出口处,同时检查dont_track_primary和nopreempt这两个提前返回分支。

我给测试环境打了补丁后,重新用valgrind跑了一遍,重点确认两件事:

  1. LEAK SUMMARY里之前的definitely lost记录消失了;
  2. massif的堆峰值图变成了一条平稳的直线,锯齿不再上移。

补丁验证通过后,灰度到一台低流量的测试业务机上,跑了72小时,用/proc/PID/status采样RSS。结果很干净:RSS稳定在75MB左右,没有持续增长。

再把补丁同步到所有生产节点,先升级backup节点,做一次主备切换确认状态机正常,再升级原master节点。稳定运行两周后,RSS曲线完全是一条直线。这个问题算是真正收尾了。

线上和其他业务侧的keepalived节点,如果不是IPv6且不带需要分片的大通告报文,理论上不会触发这个泄漏,但本着统一版本管理原则,我还是建议全部升到包含修复的版本。

6.2 复盘:这类内存泄漏定位的方法论

把这个排障流程提炼一下,实际上有几个关键节点值得记住:

第一,区分"glibc堆复用虚高"和"真实泄漏"。很多人一看到top里RSS涨就慌,但RSS涨不一定是泄漏,glibc的malloc回收策略经常造成假象。第一步永远是看进程真正in use的字节数,而不是看RSS。

第二,周期性泄漏的判定标准。持续缓慢上涨,且上涨节奏和某个业务周期(VRRP通告周期、健康检查周期、日志刷盘周期、连接池清理周期)同步,那90%是周期性路径里的分配/释放不对称问题。

第三,工具的选用顺序要由便宜到昂贵。先看/proc和日志,再做配置审计,再用malloc_stats和pmap,然后strace观察系统调用模式,最后才上valgrind/massif。原因很简单,valgrind在长驻进程上很难一次性直接烙准,而且性能损耗可能改变进程行为,前面所有观察都是为了缩小复现场景,让valgrind的一次运行就能命中。

第四,valgrind只能报告"有泄漏",不能报告"为什么泄漏"。要结合源码审计和gdb断点跟踪,把调用栈和具体分支对上,才能给出修复方案。很多初学者拿到valgrind报告就直接搜函数名,而忽视了分支条件,这会导致改了代码但泄漏依旧。

6.3 一点实际运维体会

这次排障最耗时间的其实不是定位本身,而是复现环境的搭建。keepalived这种状态机类进程,你很难在测试环境100%模拟生产环境的报文大小和状态切换频率。我最后能快速复现,靠的是把通告周期调到200ms、把报文内容填大、把IPv6分片路径稳定触发,这三件事缺一不可。

还有一个细节想多说一句:在/proc/PID/smaps里观察heap段的同时,记得看一眼numa相关的内存分布。我们有一台测试机出现过RSS和heap对不上号的情况,最后发现是numa策略导致的跨节点内存分配,进程实际用到的内存分散在两个NUMA节点上,top里看到的RSS会被系统层面的统计方式影响。这个问题在keepalived这种长时间运行的进程上不常见,但如果你的服务器开了numa balancing,遇到内存增长异常时多查一个维度总没坏处。

另外在写监控告警时,我后来把RSS采集从top的一次性快照改成了基于/proc/PID/status的连续变化趋势判断,并且把阈值设置成"连续24小时增长超过20%"而不是某个绝对值。绝对值经常因为glibc堆复用造成误报,但趋势阈值能很稳地捕捉到真实泄漏。这个经验现在一直被用在其他第三方网络进程的监控上。

相关新闻

AI Agent场景下的大模型性能评估:核心维度与实操方法

AI Agent场景下的大模型性能评估:核心维度与实操方法

1. 项目概述1.1 核心需求解析先聊一个我在工作时经常被问到的问题:给大模型做个性能打分,到底是在测什么?是想知道它能不能一口气答对一百道数学题,还是想搞清楚它在真实的业务环境里能不能稳定输出?如果是针对AI Agen…

2026/10/20 20:36:02 阅读更多 →
requests爬京东评论稳态方案:抗反爬、防丢数、结构化落盘

requests爬京东评论稳态方案:抗反爬、防丢数、结构化落盘

简介:本资源是一套基于Python requests库实现的京东商品评论爬取与分类保存实战项目,面向Python初学者及网络数据采集爱好者,解决电商评论数据自动化获取、清洗与结构化存储的实际问题。压缩包共7个文件,含3个CSV(分别…

2026/10/20 20:35:00 阅读更多 →
液冷比风冷贵?2兆瓦数据中心投资成本拆解:10kW打平,40kW省14%

液冷比风冷贵?2兆瓦数据中心投资成本拆解:10kW打平,40kW省14%

简介:这份PDF白皮书聚焦大型数据中心制冷方案的投资成本对比,面向数据中心设计者、运维人员及基础设施规划者,帮助其在风冷与浸没式液冷之间做出有数据支撑的选型决策。资源为1个PDF文件,压缩包约1.67MB,内容源自施耐德…

2026/10/20 20:35:00 阅读更多 →

最新新闻

服务器磁盘管理实战:从选型、RAID到LVM与性能排障全解析

服务器磁盘管理实战:从选型、RAID到LVM与性能排障全解析

最近帮一个业务团队做新服务器选型与磁盘初始化配置时,发现很多开发同学对磁盘这块的知识还停留在“机械硬盘 vs 固态硬盘”的层面。真要落到服务器选型、多块硬盘怎么组合、RAID 怎么选、系统装完以后磁盘怎么规划、后续怎么扩容和排障,往往就缺乏一套完…

2026/10/21 2:49:01 阅读更多 →
RAG知识库问答实战:从原理、技术选型到工程落地优化

RAG知识库问答实战:从原理、技术选型到工程落地优化

1. RAG 到底解决了什么问题,为什么现在非学不可最近两年,大模型相关的技术方向非常多,微调、Agent、多模态、RAG……如果不深入去看,很容易被各种名词绕晕。尤其是 RAG(Retrieval-Augmented Generation,检索…

2026/10/21 2:49:01 阅读更多 →
RAG知识库问答实战:从原理到代码落地

RAG知识库问答实战:从原理到代码落地

前一阵子在做知识库问答项目时,发现网上 RAG 相关的教程虽然很多,但大部分要么只讲原理、不给可运行代码,要么代码能跑但不解释为什么这么设计。对刚接触大模型应用开发的同学来说,很容易卡在“原理看懂了,一动手就报错…

2026/10/21 2:49:01 阅读更多 →
RAG入门到实战:用LangChain+Chroma搭建知识库问答系统

RAG入门到实战:用LangChain+Chroma搭建知识库问答系统

先给结论:RAG 是目前搭建知识库问答最稳的基线方案。RAG 的全称是 Retrieval-Augmented Generation,检索增强生成。它解决的问题很直接:大模型不知道你的私有资料、内部文档、产品手册和业务数据,那就先把这些资料切块、向量化、存…

2026/10/21 2:49:01 阅读更多 →
火焰数据集YOLOv5训练实战:从标注文件到可推理模型

火焰数据集YOLOv5训练实战:从标注文件到可推理模型

简介:火焰数据集(含标注好的标签)面向从事目标检测的开发者与研究者,尤其适合使用 YOLOv5 训练火焰识别模型的场景,可用于火灾预警、视频监控等实际项目。资源包共 5260 个文件,包含 1853 张 jpg 图像、185…

2026/10/21 2:49:01 阅读更多 →
Quartz动态设置并发数量

Quartz动态设置并发数量

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

2026/10/21 2:48:00 阅读更多 →

日新闻

统一内存+量化:锐龙AI Max PRO 400如何本地跑320B大模型

统一内存+量化:锐龙AI Max PRO 400如何本地跑320B大模型

这段时间硬件圈和AI圈都在传一个事:AMD锐龙AI Max PRO 400系列把最高192GB统一内存搬进了PC形态的产品里,按宣传口径,本地跑320B参数的大家伙不再是纸面概念。我第一反应倒不是“内存真大”,而是这话背后的含金量——它把过去只能…

2026/10/21 0:00:11 阅读更多 →
AI助手深度使用体验:对话质量、长文本处理与指令遵循如何留住用户

AI助手深度使用体验:对话质量、长文本处理与指令遵循如何留住用户

1. 从“封号重开”这个行为说起:用户到底在追求什么“封号重开”这四个字,放在任何产品语境里都带着一股决绝的味道。一个账号从零开始积累使用记录、调教偏好、沉淀工作流,背后是大量的时间和精力成本。正常情况下,没有人愿意主动…

2026/10/21 0:00:11 阅读更多 →
ROS中YOLOv3工程落地:通信同步、坐标变换与性能调优

ROS中YOLOv3工程落地:通信同步、坐标变换与性能调优

1. 为什么在ROS里硬刚YOLOv3不是“炫技”,而是工程落地的必经之路我第一次在某高校机器人实验室看到那台搭载Jetson TX2的移动底盘原地打转、反复识别错垃圾桶时,就意识到:单纯跑通darknet_ros demo和真正让YOLOv3在ROS里“干活”&#xff0c…

2026/10/21 0:00:11 阅读更多 →

周新闻

基于GMM的语音识别系统原理与MATLAB实现详解

基于GMM的语音识别系统原理与MATLAB实现详解

说到基于高斯混合模型(GMM)的语音识别系统,很多人第一反应就是一堆数学公式,觉得门槛很高。但如果你真的在MATLAB里把它落地跑通,会发现核心其实就是三件事:把声音变成特征向量,用GMM给每个类别…

2026/10/20 10:02:13 阅读更多 →
数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理入门:反白、灰度化、调色板修改与导出txt实践

数字图像处理这四个字听起来挺唬人,但落到具体操作上,无非就是让计算机按你的想法“摆弄”像素。我在一个模拟项目X里用了一套特别经典的基础处理流程:对图像做反白、改调色板、彩色转灰度,最后把像素数据导出成txt文件。单看每一…

2026/10/20 20:43:59 阅读更多 →
机器人大脑技术盘点:具身智能的感知、决策与数据闭环

机器人大脑技术盘点:具身智能的感知、决策与数据闭环

如果你的信息流最近也天天刷到“机器人大脑”这个词,你会发现一个很有意思的现象:每个人说的“大脑”根本不是同一个东西。有人指的是大语言模型,有人指的是运动控制系统,还有人指的是能理解物理世界的端到端模型。在2026年这个时…

2026/10/20 2:50:50 阅读更多 →

月新闻

我发现了一个新思路:用 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/20 10:02:08 阅读更多 →
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/20 9:50:17 阅读更多 →
黑夜航拍船只数据集训练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/20 9:50:45 阅读更多 →