LeakCanary原理全解析:Android内存泄漏自动化检测与实战指南
1. 项目概述为什么我们需要一个“内存泄漏捕手”在Android开发这个行当里内存泄漏Memory Leak是个老生常谈却又让人头疼不已的问题。它不像空指针异常那样会立刻导致应用崩溃给你一个明确的错误堆栈。内存泄漏更像是一个隐形的“资源小偷”悄无声息地蚕食着应用的堆内存。初期你可能毫无察觉但随着用户使用时间的增长尤其是在低端设备上应用会逐渐变得卡顿、响应迟缓最终可能因为OutOfMemoryError而崩溃用户体验一落千丈。更棘手的是这类问题在开发和测试阶段很难被复现往往到了线上通过用户反馈和崩溃监控才后知后觉。传统的排查手段比如分析hprof堆转储文件过程繁琐且门槛较高。你需要手动触发堆转储然后用MAT或者Android Studio的Profiler去分析面对海量的对象引用关系图就像大海捞针效率低下。正是在这种背景下LeakCanary应运而生。它由Square公司开源名字直译过来就是“泄漏的金丝雀”。这个典故来源于矿工用金丝雀来预警有毒气体而LeakCanary在应用中的作用也类似——它是一个自动化的内存泄漏检测库能在开发阶段就充当“预警系统”帮你快速定位并修复泄漏点。简单来说LeakCanary的核心价值在于自动化和可视化。它自动监控Activity、Fragment、View等容易被误用的组件的生命周期在它们本该被销毁却依然被持有即发生泄漏时自动抓取堆内存快照进行分析并以最清晰的方式告诉你“嘿这里有个泄漏是哪个对象持有了它导致它无法被回收。” 对于开发者而言这相当于拥有了一位24小时在线的内存专家极大地提升了排查效率和代码质量。接下来我们就深入它的“五脏六腑”看看这只“金丝雀”是如何工作的。2. 核心架构与工作流程拆解LeakCanary的运作并非一个简单的“if-else”判断而是一套精心设计的、分阶段的自动化流水线。理解这套流程是掌握其原理的关键。它的核心工作流程可以清晰地划分为四个阶段监控Watch、等待Wait、确认Confirm和分析Dump Analyze。2.1 第一阶段监控Watch—— 标记观察对象这是整个流程的起点。LeakCanary并不会监控应用中的所有对象那将带来巨大的性能开销。它的监控目标是那些生命周期明确且容易因使用不当而发生泄漏的对象最典型的就是Activity、Fragment、View以及ViewModel。那么它是如何知道一个Activity被销毁了呢这里就用到了Android的生命周期感知组件。LeakCanary 2.0之后其内部实现高度依赖于androidx.lifecycle库。它会向Application注册一个ActivityLifecycleCallbacks从而监听所有Activity的生命周期事件。当一个Activity执行到onDestroy()方法时LeakCanary的监控就被触发了。此时它并不会立即认为该Activity泄漏了因为垃圾回收GC是异步的对象需要一点时间才能被回收。LeakCanary会将这个即将被销毁的Activity对象用一个KeyedWeakReference带键的弱引用包裹起来然后将其放入一个专门的监控队列中。这里有两个关键设计使用弱引用WeakReference弱引用是Java中一种特殊的引用类型它不会阻止其所指对象被垃圾回收器回收。这意味着如果这个Activity对象除了这个弱引用之外没有其他强引用链可达那么在下一次GC发生时它就会被回收。LeakCanary正是利用这一点来判断对象是否存活。使用唯一的Key每个被监控的对象都会关联一个唯一的标识符如UUID。这个Key用于在后续流程中从堆转储文件里精准地定位我们之前监控的那个对象实例而不是其他同类的对象。注意很多开发者误以为LeakCanary一检测到onDestroy就报泄漏其实不然。它非常“谨慎”给了对象被GC回收的机会。这避免了因GC延迟而导致的误报。2.2 第二阶段等待Wait与确认Confirm—— 给予GC机会并验证将对象加入监控队列后LeakCanary会等待一段时间默认是5秒然后手动触发一次垃圾回收通过Runtime.getRuntime().gc()。触发GC后它会再次检查那个KeyedWeakReference。如果KeyedWeakReference.get()返回null恭喜这说明我们监控的对象已经被GC回收了。没有强引用指向它一切正常LeakCanary会安静地结束对这个对象的监控流程终止。如果KeyedWeakReference.get()仍然能拿到那个Activity对象警报初步拉响这说明至少有一条强引用链仍然持有这个Activity阻止了GC回收它。对象“疑似”泄漏。但是“疑似”还不够。为了应对一些极端情况比如Finalizer队列延迟等LeakCanary会进入“确认”阶段。它会再等待一段时间默认也是5秒再次触发一次GC然后复查。如果两次检查后对象依然存活那么LeakCanary就确认它发生了内存泄漏。这个“二次确认”机制进一步降低了误报率。2.3 第三阶段转储与分析Dump Analyze—— 捕捉现场并破案一旦确认泄漏就需要找到“凶手”——那条不该存在的强引用链。这时LeakCanary会做两件重量级的事情堆转储Heap Dump调用Android SDK的Debug.dumpHprofData()方法将当前JVM的堆内存状态完整地保存到一个.hprof文件中。这个文件包含了此刻内存中所有对象及其引用关系的完整快照。堆分析Heap Analysis这是最核心、最复杂的部分。LeakCanary内置了一个名为Shark的堆分析器早期版本使用HAHA库后来自研了更快的Shark。分析过程主要分为几步解析hprof文件Shark会以流式、低内存占用的方式解析巨大的hprof文件构建出内存中对象图的结构。查找泄漏对象根据第一阶段生成的唯一Key在对象图中找到那个本应被回收却依然存在的对象实例。构建引用路径从该泄漏对象出发向它的“根GC Root”回溯找出所有持有它的引用链。GC Root是一类特殊的对象如静态变量、线程栈中的局部变量等它们不会被GC回收。剪枝与优化默认情况下LeakCanary会过滤掉一些系统内部或已知的、不会造成问题的引用如mDestroyed字段展示一条最简短、最可能由开发者代码导致泄漏的引用链。这条链的末端Leak Trace的底部就是泄漏对象链的顶端顶部通常是GC Root而中间环节就是你的代码中持有它的对象。分析完成后LeakCanary会以非常友好的方式将结果通知给你在Android Studio的Logcat中输出详细的引用链同时会在设备上生成一个通知点击后能看到可视化的泄漏轨迹图直接指向你的代码文件和行号。3. 核心组件与关键技术原理解析了解了宏观流程我们再深入到几个核心组件的内部看看它们是如何协作完成这项精密任务的。3.1ObjectWatcher内存监视器的核心ObjectWatcher是LeakCanary的大脑负责管理所有被监控的对象。它的内部维护了一个MapKey是前面提到的唯一标识符Value就是那个KeyedWeakReference。// 概念性代码展示核心逻辑 class ObjectWatcher { private val watchedObjects mutableMapOfString, KeyedWeakReference() private val queue ReferenceQueueAny() // 用于接收被回收对象的通知 fun watch(watchedObject: Any, key: String) { // 创建弱引用并关联引用队列 val reference KeyedWeakReference(watchedObject, key, queue) watchedObjects[key] reference } fun removeWatchedObject(key: String) { ... } // 检查有哪些对象已被回收 fun pollDeletedObjects(): ListKeyedWeakReference { val removedItems mutableListOfKeyedWeakReference() var ref: KeyedWeakReference? queue.poll() as? KeyedWeakReference while (ref ! null) { removedItems.add(ref) watchedObjects.remove(ref.key) ref queue.poll() as? KeyedWeakReference } return removedItems } }关键机制ReferenceQueue这是Java提供的一个配合WeakReference使用的队列。当一个弱引用所指向的对象被GC回收后这个弱引用对象本身会被JVM自动放入其注册的ReferenceQueue中。ObjectWatcher通过定期或触发检查时轮询poll这个队列就能知道哪些被监控的对象已经“消失”了从而将其从监控列表中移除。仍在列表中的就是“疑似泄漏”的对象。3.2HeapDumpTrigger与HeapDumper触发与执行堆转储HeapDumpTrigger是决策者它封装了前面提到的“等待-确认”逻辑。它持有一个ObjectWatcher并会定期或由ActivityDestroyed等事件驱动执行检查任务checkRetainedObjects。HeapDumper是执行者它的实现AndroidHeapDumper直接调用了Debug.dumpHprofData(filePath)这个原生API。生成堆转储文件是一个阻塞式的、高开销的操作会导致应用线程暂停数秒时间取决于堆大小。因此LeakCanary默认只在调试版本debug build中启用并且会显示一个正在dump的Toast提示用户。3.3Shark新一代高性能堆分析引擎Shark取代了旧的HAHA库其优势在于速度和内存效率。它不再需要将整个hprof文件加载到内存中构建庞大的对象图而是采用索引化和按需解析的策略。索引化快速扫描hprof文件构建出对象ID、类信息、实例数据等位置的索引而不是立即解析所有内容。按需查找当需要分析某个特定对象根据Key查找的引用链时Shark利用索引只加载与这条路径相关的部分数据到内存中进行计算。这大大降低了内存峰值使用量和分析时间。路径查找算法Shark使用图遍历算法如BFS从泄漏对象开始逆向遍历引用关系寻找通往GC Root的路径。它会智能地忽略一些已知的“噪音”引用提供最简洁的泄漏轨迹。3.4 对Fragment和ViewModel等组件的监控对于Fragment监控时机更为复杂因为它的生命周期并不完全和Activity绑定。LeakCanary通过注册FragmentManager.FragmentLifecycleCallbacks来监听Fragment的销毁。对于ViewModel则是利用其onCleared()回调作为监控点。一个重要的细节LeakCanary 2.x 通过AppWatcher提供了自动安装功能只需添加依赖即可监控Activity和Fragment。但对于ViewModel、View等需要手动调用AppWatcher.objectWatcher.watch(viewModel)。这是因为ViewModel的清除逻辑在架构组件内部LeakCanary无法自动插入监控点。4. 高级配置、最佳实践与避坑指南理解了原理我们来看看如何在项目中高效、正确地使用LeakCanary并避开一些常见的“坑”。4.1 基础集成与配置集成非常简单在app模块的build.gradle中添加依赖即可注意使用debugImplementation避免泄漏到正式版dependencies { debugImplementation com.squareup.leakcanary:leakcanary-android:2.12 }默认配置对于大多数项目已经足够。但你可以通过自定义AppWatcher的配置来调整行为// 在 Application.onCreate() 中配置 class MyApp : Application() { override fun onCreate() { super.onCreate() val config LeakCanary.config.copy( // 调整“等待”和“确认”阶段的时间 watchDurationMillis TimeUnit.SECONDS.toMillis(10), // 默认5秒 // 是否在dump堆时显示通知 dumpHeap true, // 自定义需要忽略的泄漏如已知的第三方库问题 referenceMatchers AndroidReferenceMatchers.appDefaults IgnoredReferenceMatcher( pattern com.example.SomeLibraryClass, description 这是一个已知的第三方库泄漏已提issue ) ) LeakCanary.config config } }4.2 监控自定义对象与资源除了内置组件你完全可以监控任何你认为可能泄漏的对象。例如一个单例持有了一个Contextclass MySingleton(private val context: Context) { init { // 在合适的时机比如单例销毁时监控context // 但更好的做法是避免持有Context传递Application Context } fun onDestroy() { AppWatcher.objectWatcher.watch(context, MySingleton.context) } }更常见的场景是监控关闭的资源如BroadcastReceiver、FileOutputStream等确保它们在onDestroy或onCleared中被正确释放。4.3 解读泄漏报告与实战排查当泄漏通知出现时点击查看详情你会看到类似下面的引用链简化┬─── │ GC Root: Static field com.example.MyApplication.sInstance │ ├─ com.example.MyApplication instance │ Leaking: NO (Application is a singleton) │ ↓ MyApplication.someSingleton │ ~~~~~~~~~~~~ ├─ com.example.SomeSingleton instance │ Leaking: UNKNOWN │ ↓ SomeSingleton.activityRef │ ~~~~~~~~~~~ ├─ android.app.Activity instance │ Leaking: YES (ObjectWatcher watched this) │ ↓ Activity.mContentView │ ~~~~~~~~~~~~ ╰→ android.widget.TextView instance如何阅读┬───表示引用链的开始。│和├─表示引用链中的一环。↓表示引用关系。Leaking: YES/NO/UNKNOWN表示LeakCanary对该节点泄漏状态的判断。最后一行╰→指向的就是发生泄漏的对象实例。排查步骤找到你的代码从泄漏报告底部往上找第一个属于你项目包名的类通常就是问题的关键。分析引用关系看这个类是如何被持有的。常见罪魁祸首有静态变量、匿名内部类/Handler、单例、未取消的注册如广播、监听器、生命周期更长的组件如ViewModel持有了View的引用。修复泄漏根据引用关系打破错误的持有链。例如将强引用改为弱引用在生命周期结束时置空引用或使用Lifecycle感知的组件如LiveData、Flow来替代直接持有。4.4 常见问题与避坑心得“LeakCanary本身导致OOM或卡顿”原因堆转储dumpHprof过程会暂停所有线程耗时较长几秒到几十秒内存占用激增。解决这是预期行为。务必仅在debug构建中使用。对于大型应用可以考虑在LeakCanary.config中增加watchDurationMillis减少检查频率或在自动化测试中集中使用。“误报”或“看不懂的泄漏轨迹”系统资源泄漏有些泄漏来自Android系统本身或厂商ROM报告中可能显示InputMethodManager、ActivityThread等系统类。这类问题通常无法在应用层修复可以将其添加到IgnoredReferenceMatcher中忽略。已知的第三方库问题一些流行库在特定版本存在已知泄漏。关注库的Issue升级版本或同样将其加入忽略列表。“Release包也想监控但不想影响用户”LeakCanary提供了leakcanary-object-watcher-android和leakcanary-shark等独立模块。你可以集成这些模块在Release版中只收集堆转储文件hprof而不在设备上分析。然后将这些文件上传到你的服务器在后台用Shark进行分析。这需要一定的后端支持。“监控ViewModel或View不生效”记住对于非Activity/Fragment需要手动调用watch方法。最佳时机是在该对象确定不再被需要时如ViewModel的onClearedView的onDetachedFromWindow。“如何编写内存泄漏的单元测试或自动化测试”可以利用AppWatcher的objectWatcher的hasRetainedObjects或retainedObjectCount属性在测试的After方法中断言没有对象被滞留。结合Espresso等UI测试框架在完成一系列操作后检查内存状态。5. 性能影响分析与生产环境考量将LeakCanary集成到应用中尤其是在生产环境必须权衡其带来的收益和开销。5.1 性能开销明细运行时监控开销极低。主要是ObjectWatcher维护一个弱引用映射表以及定期检查的少量计算。这对应用性能的影响微乎其微可以忽略。堆转储开销非常高。这是最主要的影响点。Debug.dumpHprofData()是一个同步阻塞调用会“冻结”应用所有线程直到整个堆内存被写入磁盘。持续时间与堆内存大小成正比通常在2-10秒之间期间应用无响应。同时写入过程会产生大量的I/O操作。堆分析开销较高。分析hprof文件需要消耗可观的CPU和内存资源。虽然Shark优化得很好但对于大堆文件分析仍可能需要数秒到数十秒并产生数百MB的内存峰值。5.2 生产环境Release使用策略鉴于上述开销绝对不建议在面向用户的Release版本中默认开启完整的LeakCanary功能即watchdumpanalyze。但这不意味着生产环境就无法进行内存监控。可以采用以下分层策略仅监控不转储轻量级方案集成leakcanary-object-watcher-android核心监控模块。配置为只执行“监控”和“等待确认”阶段。一旦确认泄漏不执行堆转储而是通过日志或监控平台上报一个事件记录泄漏对象的类名和Key。这样开销极小可以全量开启。它能告诉你“有泄漏发生”但不知道“具体哪里泄漏”。适用于发现泄漏趋势和严重程度。采样转储与分析在方案1的基础上对一小部分用户例如0.1%或更少或满足特定条件如泄漏对象数量超过阈值时才触发完整的堆转储和分析。可以将堆转储文件上传到服务器在服务端利用Shark进行分析避免消耗用户设备的资源。这需要搭建相应的后端服务来接收和处理hprof文件。结合现有APM平台许多商业APM应用性能管理平台如Firebase Performance Monitoring、New Relic等也提供内存泄漏监控功能。它们通常采用了更复杂、更低开销的采样和上报机制。可以将LeakCanary作为一个更强大、更精确的补充工具用于在开发和测试阶段进行深度排查而生产环境依赖APM的宏观监控。5.3 与Android Studio Profiler的对比与协作LeakCanary和Android Studio Profiler是互补而非替代的关系。LeakCanary主动、自动化、精准定位。它像一位自动巡检的保安发现可疑目标立即报警并给出详细报告。优势在于自动化能捕捉到那些间歇性、难以手动复现的泄漏。Android Studio Profiler手动、全局、深度分析。它像一套精密的医疗检测仪器需要你手动操作来录制内存分配、捕获堆转储然后提供全方位的分析视图如按类分布、引用树、分配调用栈。优势在于全局视野和深度可以分析内存增长趋势、所有对象的状态而不仅仅是泄漏。最佳实践在日常开发中依赖LeakCanary进行自动化检测和快速定位。当遇到LeakCanary无法解释的复杂内存问题如整体内存持续增长但无明确泄漏点时再使用Android Studio Profiler进行手动的、长时间的录制和深度分析。两者结合能构建起从快速响应到深度排查的完整内存优化体系。理解LeakCanary的工作原理不仅是为了用好这个工具更是为了加深对Android内存管理、垃圾回收机制以及对象引用生命周期的理解。它迫使你以更严谨的方式去思考对象之间的持有关系从而在编码之初就避免许多潜在的内存陷阱。这只“金丝雀”的价值远不止于报错更在于培养开发者良好的内存意识。

相关新闻

Linux系统重启记录查看:last、uptime与日志排查全解析

Linux系统重启记录查看:last、uptime与日志排查全解析

1. 项目概述:为什么我们需要查看Linux重启记录?在日常运维、系统排障或者安全审计工作中,有一个看似简单却至关重要的需求:搞清楚这台Linux服务器什么时候重启过,以及为什么重启。无论是半夜被报警叫醒,发现…

2026/10/18 14:37:16 阅读更多 →
ESP-IDF开发实战避坑指南:从环境搭建到系统优化的全流程解析

ESP-IDF开发实战避坑指南:从环境搭建到系统优化的全流程解析

1. 项目概述:为什么我们需要一份ESP-IDF避坑指南 如果你正在用ESP32做产品开发,或者刚从Arduino转向更底层的ESP-IDF,那你大概率已经踩过一些坑了。ESP-IDF作为乐鑫官方的物联网开发框架,功能强大、控制精细,但它的学习…

2026/10/16 20:14:47 阅读更多 →
Python爬虫入门实战:从零构建小说采集与TXT保存工具

Python爬虫入门实战:从零构建小说采集与TXT保存工具

1. 项目概述与核心价值 最近在技术社区和论坛里,看到不少朋友在问如何用Python爬取网络小说,然后保存成本地TXT文件。这确实是一个非常适合Python初学者练手的项目,它几乎涵盖了爬虫入门的所有核心环节:发送请求、解析网页、处理数…

2026/10/15 12:25:11 阅读更多 →

最新新闻

不用Django,把机器学习预测结果展示到HTML页面的三种方案

不用Django,把机器学习预测结果展示到HTML页面的三种方案

最近我遇到一个挺常见的需求:机器学习模型跑完,预测结果还躺在 notebook 里,可客户那边只想打开一个网页就能看到实时预测效果。我第一反应是上 Django,但项目本身不大,真不想为了一个展示页搭一套全家桶。于是问题就来…

2026/10/19 13:08:32 阅读更多 →
open-code-review:从人治到规则治的代码审查实践指南

open-code-review:从人治到规则治的代码审查实践指南

1. 为什么“open-code-review”值得单独拿出来聊第一次听到“open-code-review”这个词,很多人会下意识觉得它只是“代码审查”的又一个新包装。但真正在团队里推过代码审查的人都知道,这件事的难点从来不在“审查”两个字,而在于“open”——…

2026/10/19 13:08:32 阅读更多 →
代码评审工具化实践:从规则引擎到流程编排的轻量集成方案

代码评审工具化实践:从规则引擎到流程编排的轻量集成方案

1. 为什么"代码评审"这件事值得单独拿出来做一套工具但凡在研发团队里待过几年的人,都会对"代码评审"这件事又爱又恨。爱的是它确实能拦住不少低级错误,恨的是它经常变成走过场——要么是评审人扫两眼就点了通过,要么是作…

2026/10/19 13:08:32 阅读更多 →
SSM+Vue客房订餐系统毕业设计完整实现与论文写作指南

SSM+Vue客房订餐系统毕业设计完整实现与论文写作指南

每年到了毕设季,我都习惯先看一眼市面上都在做哪些题目。说实话,像“ssmvue客房订餐系统”这种组合,几乎是每年都会出现的经典选题,但真正能把论文和程序都做得扎实的同学,比例并不高。这篇文章就把这个项目的完整拆解…

2026/10/19 13:08:32 阅读更多 →
JSP+Access手机销售系统:零配置Java Web教学项目

JSP+Access手机销售系统:零配置Java Web教学项目

简介:本资源是一套面向Java初学者与高校课程设计学生的完整JSP Web项目实践材料,聚焦手机销售业务场景,解决小型商贸系统开发入门难、文档不全、代码缺调试环境等常见痛点。压缩包共含项目报告、开题报告、需求分析说明书、详细设计说明书、数…

2026/10/19 13:08:32 阅读更多 →
百考通AI一键生成任务书:从模板到内容的高效实践

百考通AI一键生成任务书:从模板到内容的高效实践

1. 项目概述:从乱糟糟到标准化的“一键生成”做毕设、申报课题、安排项目任务,最让人头疼的往往不是干活本身,而是动笔写那几百字上千字的任务书。格式要规范、目标要明确、步骤要清楚、时间节点要合理,每一项都是磨人的细节。我自…

2026/10/19 13:07:29 阅读更多 →

日新闻

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

频率跟踪型PWM电源设计:臭氧发生器谐振点漂移与软开关实现

简介:本资源为电源技术方向的学术研究文档,聚焦介质阻挡放电型臭氧发生器电源的频率跟踪型PWM控制策略,面向电力电子、高压电源及臭氧应用领域的科研人员与工程技术人员。针对负载呈容性、等效电容随外加电压升高而增大、谐振频率随之漂移的难…

2026/10/19 0:00:47 阅读更多 →
Vibe Coding 遇上 TaoToken:把开发者思维圣殿的灵感流接入统一 Key 通道

Vibe Coding 遇上 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/19 0:00:47 阅读更多 →
HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

HundredCV-Chat话题建模实战教程:利用4,871个内置话题标签构建主题分析系统

【免费下载链接】HundredCV-Chat 项目地址: https://ai.gitcode.com/hf_mirrors/Jax-dan/HundredCV-Chat 点击查看 免费下载 HundredCV-Chat 是一个由 100 位青年简历数据开发而来的中文多轮对话数据集,共包含 24,750 组日常闲聊对话和 4,871 个话题标签…

2026/10/19 0:00:47 阅读更多 →

周新闻

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

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

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

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

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

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

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

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

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

2026/10/19 1:30:52 阅读更多 →

月新闻

我发现了一个新思路:用 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/19 2:54:50 阅读更多 →
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/19 9:10:22 阅读更多 →
黑夜航拍船只数据集训练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/18 12:16:16 阅读更多 →