JVM堆转储实战:不同运行阶段的内存排查与生成策略

排查 JVM 内存问题时,堆转储(heap dump)是最硬核的证据。它能把你程序在某个瞬间的堆内存状态完整拍下来,哪些对象占了多少内存、被谁引用、链路是怎么串起来的,一眼就能看到底。问题是,堆转储不是乱拍就行,Java 程序在启动阶段、稳定运行阶段、高并发阶段、OOM 崩溃阶段的内存画像完全不一样,拍照的时机和方式差一点,结论就可能完全不同。这篇文章我会把我在实际项目里用过的各种生成方式,按运行阶段拆开讲清楚。适用对象是正在和内存泄漏、Full GC、OOM 打交道的 Java 开发,也适合刚接触 JVM 排查的运维同学。

1. 先搞清楚堆转储到底拍到了什么

1.1 堆转储不是简单的内存统计

很多同学第一次接触堆转储,以为它就是一个“内存占用排行表”。实际上 .hprof 文件里装的信息远比这丰富:加载的类、类的实例对象、数组、基础类型字段、对象引用关系、GC Roots 的起点、线程栈里引用的局部变量,甚至每个对象所在的包和类加载器都能找出来。

这么说吧,普通的内存监控告诉你“现在堆用了 3GB”,堆转储则能告诉你“这 3GB 是被谁用的、从哪条引用链到这里的”。排查内存泄漏时,光知道内存涨没用,必须顺着引用链条找到那个“握着大对象不放”的根。堆转储就是把现场固定下来,让你可以离线把链条一段一段捋清楚。

但也要注意,堆转储不等于线程转储。它虽然会记录一些线程栈信息,但核心是堆内存里的对象关系。如果想查死锁、线程池膨胀、CPU 飙高,那该抓的是 thread dump,不是 heap dump。

1.2 不同运行阶段的内存画像差异

我在实际排查里发现,Java 应用的内存问题往往不是均匀出现的。不同阶段的内存画像差异非常大:

  • 启动阶段:类加载、Spring 容器初始化、各种连接池预热、缓存拉起都在抢内存。这个阶段常见的是“元空间压力大”或者“初始化逻辑里持有大量临时对象”,堆转储可以帮你确认哪些类被重复加载、哪些静态容器在启动时就被塞了不该常驻的数据。
  • 稳定运行阶段:正常情况下堆里主要是业务对象、缓存、线程池缓冲区和 IO 缓冲。这时候抓堆转储特别适合做基线,方便以后问题发生时对比。
  • 高峰期阶段:大量请求同时涌入,业务对象、队列、会话数据会在短时间内堆积。此时抓堆转储能看到瞬时压力是发生在“请求堆积”还是“缓存膨胀”上。
  • OOM/崩溃阶段:内存已经被耗尽,JVM 正在挣扎或已经准备退出。这个瞬间的堆转储往往是破案关键,能直接看出来是泄漏还是“一次性峰值超出了设置”。

只抓一次堆转储,就相当于只拍了一张照片。如果恰好是深夜低峰期拍到的,那可能什么都看不出来。这也是“按运行阶段生成堆转储”的核心逻辑:在不同时间点反复采样,才能发现内存变化的趋势,而不是只守着最后一次 OOM。

2. 用 JVM 参数让堆转储在正确时机自动落盘

2.1 OOM 发生时的兜底参数

最推荐先配上的,就是 JVM 自带的 OOM 自动堆转储。只要在启动命令里加上:

java -Xmx4g \ -XX:+HeapDumpOnOutOfMemoryError \ -XX:HeapDumpPath=/data/dumps/order-service.hprof \ -jar order-service.jar

当 JVM 抛出OutOfMemoryError时,会自动把当时的堆状态写入指定路径。如果不配HeapDumpPath,JDK 会在进程的工作目录下生成一个类似java_pid12345.hprof的文件,位置说老实话不太好找,而且如果工作目录和程序目录空间不够,dump 会直接失败。

这个参数我建议所有线上 Java 服务都默认加上。它平时不产生任何开销,只在 OOM 时生效。真正出问题时,你至少有“最后一眼”的证据,不会只有一行报错日志。

另外可以搭配-XX:+ExitOnOutOfMemoryError,让 JVM 在 OOM 后直接退出,配合容器健康检查自动重启,至少能避免一个“半死不活”的进程继续拖着。但注意这会让服务中断,是否开启要根据业务容忍度来定。

2.2 Full GC 前后自动抓拍

OOM 是终点,但很多时候内存问题在 OOM 之前就以“频繁 Full GC”的形式表现出来了。这时候可以启用 JVM 的 Full GC 前后堆转储参数:

java -Xmx4g \ -XX:+HeapDumpBeforeFullGC \ -XX:+HeapDumpAfterFullGC \ -XX:HeapDumpPath=/data/dumps/ \ -jar order-service.jar

看到没,这里HeapDumpPath写的是目录,生成的文件名会自动带上进程号和前后缀,避免互相覆盖。HeapDumpBeforeFullGC会抓这次 GC 之前堆变成什么样,HeapDumpAfterFullGC会抓 GC 之后还有多少对象顽强存活。

两份对照起来看特别有价值。如果 FGC 之后老年代占用率依然很高,那基本说明某些对象无法被回收,引用链必然有问题;如果 FGC 之后占用能降下来但很快又涨上去,那可能是请求峰值或者缓存刷新策略不对。

但必须泼一盆冷水:这类参数在部分垃圾收集器上有兼容性限制,而且每次 Full GC 都会额外产生 dump 文件,IO 和停顿影响叠加到线上服务上非常危险。我通常只建议在压测环境或者维护窗口临时开启,问题定位完就关掉。生产环境一直开着,等于给每个 Full GC 又加了一刀。

2.3 用监控程序按内存水位触发 dump

如果你不想等 OOM,也不想依赖 Full GC 参数,还可以在应用内部挂一个“水位触发”逻辑。核心思路是用 JMX 监控堆内存使用率,超过阈值就调用诊断接口生成堆转储。

import com.sun.management.HotSpotDiagnosticMXBean; import java.lang.management.ManagementFactory; import java.lang.management.MemoryMXBean; import java.lang.management.MemoryUsage; public class HeapDumpTrigger { public static void main(String[] args) throws Exception { MemoryMXBean memoryMXBean = ManagementFactory.getMemoryMXBean(); MemoryUsage usage = memoryMXBean.getHeapMemoryUsage(); double usedRatio = (double) usage.getUsed() / usage.getMax(); if (usedRatio > 0.85) { dumpHeap("/data/dumps/auto-" + System.currentTimeMillis() + ".hprof", false); } } private static void dumpHeap(String filePath, boolean live) throws Exception { HotSpotDiagnosticMXBean bean = ManagementFactory.getPlatformMXBean( HotSpotDiagnosticMXBean.class, com.sun.management.HotSpotDiagnosticMXBean.class); bean.dumpHeap(filePath, live); } }

注意dumpHeap的第二个参数live。如果传true,JVM 会先做一次 Full GC 再抓存活对象,这对生产环境伤害很大;如果传false,抓的是当前完整堆,虽然文件更大,但不额外触发 GC,对线上更友好。

我实际写这种触发器的时候,通常还会记录一个“上次生成时间”,防止内存水位在阈值附近抖动时连续生成几十个 dump 文件把磁盘打满。触发条件里也可以加上持续时间判断,比如“堆占用连续 30 秒超过 85%”才抓,而不是一瞬间超了就去抓。

3. 手动生成:运行期间按需快照

自动参数适合固定场景,但日常排查里更多时候是“现在内存有点不对劲,我想立刻看一眼”。这种情况下需要手动生成。

3.1 jmap:经典命令但别瞎用

jmap是 JDK 自带的老牌工具,最常用的两条命令:

# 抓完整堆 jmap -dump:format=b,file=/tmp/app-$(date +%s).hprof <pid> # 只抓存活对象 jmap -dump:live,format=b,file=/tmp/app-live.hprof <pid>

第一眼看上去很简单,但有几个点坑了很多新手。

-dump:live会先触发一次 Full GC,再抓存活对象。如果你在一台堆内存很大、业务量很高的机器上执行,这条命令本身就可能造成长时间停顿,线上事故就是这么来的。除非你非常清楚自己在做什么,否则不要在生产环境用live参数,直接用完整 dump。

完整 dump 的文件更大、对象更多,但不会主动触发 GC。分析的时候慢一点没关系,不一定非要“只保留活对象”。另外jmap需要和 Java 进程同一个系统账号权限,sudo -u要弄对,不然会报Permission denied。

3.2 jcmd:JDK 里的更优雅选择

JDK 8 以后,官方其实更推荐用jcmd,因为它能做的事情更多,而且命令风格统一。生成堆转储的命令是:

jcmd <pid> GC.heap_dump /tmp/app.hprof

如果需要抓完整堆,可以明确加-all:

jcmd <pid> GC.heap_dump -all /tmp/app.hprof

jcmd的好处是不会像jmap那样把各种参数分散开,输出信息也是结构化的。如果进程是通过-XX:+DisableAttachMechanism启动的,那jcmd和jmap都会失败,这种情况只能通过 JVM 参数自动 dump 或 JMX 方式触发。

有一点要注意:jcmd的 dump 路径如果写相对路径,是相对于 Java 进程的工作目录,而不是你当前 shell 的目录。我吃过一次亏,命令执行成功但找不到文件,后来发现文件被写到了 Tomcat 的 bin 目录底下。

4. 三个典型运行阶段的实操脚本

4.1 启动完成后的基线 dump

启动阶段抓堆转储,最好等应用完成初始化后再抓,否则堆里全是框架启动的临时对象,参考意义不大。可以写一个启动脚本,等健康检查接口通了再执行 dump:

#!/bin/bash JAR_PATH=/opt/order-service/order-service.jar PID_FILE=/tmp/order-service.pid nohup java -Xmx4g -jar "$JAR_PATH" > /var/log/order-service.log 2>&1 & PID=$! echo $PID > "$PID_FILE" # 等待健康检查通过,超时 120 秒 for i in $(seq 1 120); do if curl -sf http://127.0.0.1:8080/actuator/health; then break fi sleep 1 done # 刚起来,立刻抓一份基线 dump jcmd "$PID" GC.heap_dump /data/dumps/baseline-startup.hprof

这份基线 dump 特别适合用来对比“启动后某块静态缓存是不是被固定了”。有些内存问题不是运行时才出现的,而是程序一启动就把大量数据加载到静态集合里,等到运行一段时间后你看完整堆才恍然大悟:哦,原来从启动那一刻就已经有问题了。

4.2 低峰期定时采样

稳定运行阶段,我习惯在每天的低峰期定时生成一份堆转储,作为连续观察的采样点。比如每天凌晨两点做一次:

0 2 * * * /usr/bin/jcmd $(pgrep -f order-service.jar | head -n 1) GC.heap_dump /data/dumps/daily-$(date +\%Y\%m\%d).hprof

定时 dump 要注意两点。第一,选择低峰期是因为 dump 过程大概率会造成 JVM 停顿,哪怕只是瞬间,在白天峰值时段做容易让接口出现毛刺。第二,dump 文件通常很大,几百 MB 甚至几个 GB,连续存一个月磁盘就爆了,脚本里可以顺手做清理:

find /data/dumps -name "daily-*.hprof" -mtime +7 -delete

这份连续采样数据最有价值的地方不是单独看某一天,而是看趋势。比如某服务的byte[]对象占比从一个星期前开始缓慢上升,说明大概率有 IO 流没关闭,而不是仅有“某天大对象暴增”这种偶发问题。

4.3 高峰期触发快照

高峰期想稳定抓到快照,靠人来盯不现实。比较靠谱的方案是结合 2.3 里的水位触发器,或者用一个独立的巡检脚本去查 GC 日志和 JMX 指标。

举个例子,某订单服务高峰期出现停顿,GC 日志显示老年代占用率达到 95%。我们可以写一个简单巡检脚本,在堆使用率超过阈值时主动 dump:

#!/bin/bash PID=$(pgrep -f order-service.jar | head -n 1) USED=$(jstat -gcutil "$PID" | awk 'NR==2 {print $4}') if [ -n "$USED" ] && [ "$(echo "$USED > 90" | bc)" -eq 1 ]; then TIME=$(date +%Y%m%d-%H%M%S) jcmd "$PID" GC.heap_dump /data/dumps/peak-$TIME.hprof fi

这里jstat -gcutil第四列是老年代占用百分比,超过 90 就说明快喘不过气了。这种快照抓到的瞬间,堆里的对象构成,往往能直接反映到底是“用户并发太高,请求对象没来得及释放”还是“缓存不淘汰,一直在堆积”。前者一般伴随大量临时业务对象,后者通常能一眼看到某些集合的大小异常。

5. 堆转储分析实战:从文件到结论

光有文件不行,还要能从中提取出结论。这一节以一个常见的 OOM 排查过程为例,讲完整分析思路。

5.1 用 MAT 分析一次 OOM 的完整过程

某后台订单服务突然 OOM,启动日志里有我们配置的自动 dump 文件。先用内存分析工具打开 .hprof,我一般用 Eclipse MAT。

MAT 打开文件后会先展示“Leak Suspects”,也就是系统认为最可疑的泄漏点。它会判断哪组对象占据了最大堆内存,并给出从 GC Root 到该对象的引用链。

某次案例里,Leak Suspects 指向了一个ConcurrentHashMap,它被项目里的OrderCacheManager持有。顺着 Dominator Tree 往下看,Map 里挂了几十万个OrderInfo对象,而且这些对象都是已完成状态的订单,照理不应该继续留在缓存里。

接下用 MAT 自带的 OQL 可以快速验证:

SELECT * FROM com.example.domain.OrderInfo o WHERE o.orderStatus == 'COMPLETED'

查询结果里有大量对象,且所有对象都被同一个缓存 Map 引用。结论很清楚:缓存 load 进去之后,缺少淘汰策略;或者说是每次查询都往缓存里塞数据,但从不清理。修代码的方向变成:给缓存加过期时间、限制容量,或者在订单完成后主动移除。

分析到这一步,才算是把一个堆转储变成了一个有用的结论。注意 MAT 本身也是个 Java 程序,打开大 hprof 文件时需要给它配置大内存,否则分析工具先内存溢出了,场面就比较尴尬了。

5.2 常见内存问题的对应特征表

分析多了以后,我会根据堆里的对象特征快速判断问题类型。整理成一张表给大家当参考:

堆转储主要特征常见原因下一步排查方向
大量char[]/String对象日志侵权、JSON 序列化积压、大文本协议未释放查日志框架缓冲、业务日志输出频率
大量byte[]对象IO 流未关闭、文件读缓存、网络传输缓冲泄漏检查流资源 try-with-resources 是否覆盖所有分支
大量同一业务对象缓存未淘汰、查询结果被静态集合持有看引用链,确定是谁持有集合
大量java.lang.Thread线程池无界增长、线程没有回收配合 thread dump 判断线程栈
大量重复的 Class 对象类加载器泄漏、频繁热部署检查自定义 ClassLoader、框架 reload 逻辑

这张表不能直接套用所有场景,但可以帮你快速锁定分析方向。特征判断完之后,记得再回头用引用链验证,别看到对象多就急着下结论。

5.3 拿到 dump 后的注意事项

堆转储里可能包含用户手机号、登录 token、订单详情等敏感数据。这一点在取文件、传文件、存分析结果时都要格外注意,不该传到公共网盘的地方就放在本地离线分析,分析完及时脱敏或删除。

还有一点:分析时不要只拿一份 dump。我见过太多人只看 OOM 前的那一份,然后用它决定所有问题。如果条件允许,把启动阶段、低峰期、高峰期、OOM 前这四份放在一起对比,效果完全不一样。单独看 OOM 前,只看到“内存满了”,但不知道它是一夜之间满的,还是运行三周慢慢满的,这两种情况的处理策略完全不同。

6. 常见问题与避坑清单

6.1 生成过程中常踩的坑

每个阶段生成堆转储都有自己的坑,我整理了一份速查表:

常见问题现象解决方案
磁盘空间不足dump 文件写一半失败,或根本没生成先确认HeapDumpPath目录剩余空间,尽量预留比堆大小多一倍的容量
路径权限不对jcmd/jmap 报 Permission denied切换到启动 Java 进程的同一用户,或检查目录写权限
live 参数导致长时间停顿接口超时、GC 变长线上非必要不用-dump:live,用完整 dump
Full GC 自动 dump 参数误开系统莫名卡顿,磁盘被一堆 dump 塞满只在压测窗口临时开启,定位完关掉
容器内执行 attach 失败找不到进程,或 jcmd 连不上进入容器后确认 PID namespace,必要时从宿主机用对应工具探测
敏感信息泄露dump 文件被转发了,出现用户隐私数据限制文件权限,本地分析,不随手传聊天工具

这些坑我在真实项目里基本都碰到过。每一条看起来都挺基础,但线上环境复杂,一个小问题可能直接导致“想抓的时候抓不到”。

6.2 一些能直接抄走的经验

最后分享几个我用下来最有价值的习惯,不算什么高深技术,但能省很多事。

第一个习惯是在所有服务启动脚本里统一加上-XX:+HeapDumpOnOutOfMemoryError和-XX:HeapDumpPath,并且把路径单独挂一块大磁盘,别和系统盘混在一起。很多 OOM 恰恰发生在磁盘日志暴涨的场景,如果 dump 路径和日志路径同盘,很可能磁盘已经先满了。

第二个习惯是给堆转储文件统一命名。文件名里带上服务名、阶段、时间戳,比如order-service-peak-20250115-1430.hprof,不要裸谢app.hprof。因为一份 dump 可能是几个 GB,你不会想打开一堆文件挨个确认“这个到底是哪个服务哪个时间点抓的”。

第三个习惯是抓完之后不要只存着,要顺手记一下当天的指标:堆大小、GC 次数、CPU、并发量。分析 dump 时如果有这些背景指标,定位会快得多。比如两份 dump 的堆占用相差不大,但 GC 次数差了很多,那说明问题可能主要出在 GC 频率而不是堆大小上。

我在实际排查里最大的体会是:堆转储生成不是一键导出那么容易的事,时机、参数、命令、存储、分析每环都得对得上。按启动、稳定、峰值、OOM 这几个阶段分别把机制建好,内存问题出现的时候,你就不是靠猜,而是有证据直接说话。

相关新闻

浏览器内置网页优化引擎:DOM语义解析与实时可访问性诊断

浏览器内置网页优化引擎:DOM语义解析与实时可访问性诊断

1. 浏览器里藏着的“AI顾问”&#xff1a;不是新工具&#xff0c;而是你每天打开就用的旧功能很多人一听到“给网页提优化建议”&#xff0c;第一反应是找第三方SEO工具、装插件、注册SaaS平台&#xff0c;甚至考虑调用大模型API——结果账号要实名、额度要充值、接口要鉴权、响…

2026/10/22 14:52:57 阅读更多 →
一学就会一用就废?12周刻意练习法拆解技能学习底层方法论

一学就会一用就废?12周刻意练习法拆解技能学习底层方法论

这两年经常有人问我&#xff1a;为什么我学东西总是一学就会、一用就废&#xff1f;收藏了一堆教程、买了好几门课、笔记做了几百页&#xff0c;真到实战还是抓瞎。答案其实没那么玄乎——你练的幅度不够&#xff0c;拆的粒度不对。作为一个靠自学技能吃饭的人&#xff0c;我摸…

2026/10/21 6:32:36 阅读更多 →
计数问题全解析:从数组标记到哈希表与离散化

计数问题全解析:从数组标记到哈希表与离散化

经常刷算法题的人&#xff0c;一定见过这种场景&#xff1a;题库里躺着一道编号为1017的题&#xff0c;题面只有一句话——“求零件个数”&#xff0c;没有配图&#xff0c;没有样例解释&#xff0c;评论区一半人问这题到底啥意思&#xff0c;另一半人在贴答案错误的代码。我当…

2026/10/21 6:32:36 阅读更多 →

最新新闻

Electron桌面应用开发实战:从环境搭建到打包发布全流程

Electron桌面应用开发实战:从环境搭建到打包发布全流程

做前端这些年&#xff0c;我大部分时间都在跟浏览器标签页打交道&#xff0c;直到第一次把桌面应用跑起来&#xff0c;才发现原来自己一直被限制在地址栏和刷新按钮围起来的框框里。Electron这个词&#xff0c;最开始是在某段时间频繁出现在同事的讨论里&#xff0c;一个用HTML…

2026/10/22 10:18:38 阅读更多 →
滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

滑盖智能锁T109深度解析:结构原理、安装调试与故障排查

简介&#xff1a;亚太天能T109滑盖智能锁产品说明书是一份PDF格式的官方技术文档&#xff0c;主要面向智能锁安装人员、终端用户及售后维护者&#xff0c;帮助快速掌握产品安装、配置与常见故障处理。全包仅1个PDF文件&#xff0c;大小4.37MB&#xff0c;内容结构清晰&#xff…

2026/10/22 11:01:53 阅读更多 →
PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

PMSM弱磁控制原理与Simulink建模:高速AGV驱动系统设计指南

上个月我在调试一台高速AGV的驱动系统&#xff0c;整车要求空载跑到8m/s&#xff0c;电机转速已经拉到额定点&#xff0c;驱动器的输出电压也顶到了母线电压极限附近。再往上踩速度指令&#xff0c;转速纹丝不动&#xff0c;三相电流反而开始震荡。那会儿我的第一反应就是&…

2026/10/22 9:44:47 阅读更多 →
C++核心知识点:从内存管理到STL的实战指南

C++核心知识点:从内存管理到STL的实战指南

C 这门语言我前前后后折腾了十几年&#xff0c;用它写过嵌入式驱动、做过游戏服务端&#xff0c;也搭过基础组件库。每次看到新人一头扎进"C 核心知识点"这个搜索词&#xff0c;我其实挺感慨的——这门语言的难点从来不是语法多&#xff0c;而是知识点之间的耦合太深…

2026/10/22 10:42:00 阅读更多 →
T109滑盖智能锁怎么装?安装调试与故障排查全攻略

T109滑盖智能锁怎么装?安装调试与故障排查全攻略

简介&#xff1a;亚太天能T109滑盖智能锁产品说明书以PDF格式发布&#xff0c;适合智能锁用户、安装人员与售后维修人员阅读。内容围绕T109系列指纹密码刷卡锁展开&#xff0c;先介绍前面板、后面板、锁体、机械钥匙、电池盒盖等部件名称与功能&#xff0c;再给出完整安装步骤&…

2026/10/22 10:40:08 阅读更多 →
LLM知识降熵:从信息垄断到理解权下放

LLM知识降熵:从信息垄断到理解权下放

你有没有过这种经历&#xff1a;翻开源码注释、论文摘要或者一份专业报告&#xff0c;每个字都认识&#xff0c;连在一起却像天书。想找人聊聊&#xff0c;身边要么没人懂&#xff0c;要么懂的懒得跟你解释。后来我试着把同一段内容丢给一个大语言模型&#xff0c;几秒钟之后&a…

2026/10/22 10:56:37 阅读更多 →

日新闻

周新闻

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

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

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

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

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

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

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

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

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

2026/10/22 5:12:39 阅读更多 →

月新闻

我发现了一个新思路:用 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/21 21:50:56 阅读更多 →
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/21 21:51:55 阅读更多 →
黑夜航拍船只数据集训练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/21 16:24:48 阅读更多 →