[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"$fQ-NqSoZZxgBrWWNPKJP4Mu-P3r29lbMDrGu13c5FKJs":3},{"item":4,"related":44},{"id":5,"type":6,"title":7,"slug":8,"summary":9,"body":10,"coverUrl":11,"productScreenshots":12,"productLinks":13,"authorName":14,"authorUrl":15,"authorSubject":16,"category":17,"tags":22,"sourceLabel":35,"sourceName":36,"sourceUrl":37,"status":38,"seoTitle":7,"seoDescription":9,"canonicalUrl":35,"isFeatured":39,"sno":40,"sortOrder":41,"publishedAt":42,"updatedAt":43,"createdAt":43},"bd1746b8-937b-48cf-ae66-0116d7062e67","article","Epoch Reclamation：并发程序为什么要等“这一代线程”都走完再释放内存？","epoch-based-memory-reclamation","基于纪元的回收把退休对象标记到某一代，等所有可能看见它的参与者跨过该纪元后再批量释放，适合高并发无锁结构。","在并发程序里，直接 free 一个“看起来已经不用”的对象，往往是不安全的。另一个线程可能刚好在读取它，只是还没来得及留下明显的痕迹。Epoch-based Memory Reclamation（基于纪元的内存回收）把这个问题转换成了一个更容易管理的集体进度：只要所有可能看见旧对象的参与者都跨过了某个纪元，就可以回收这一代对象。\n\n可以把线程想成进入博物馆的参观者，把 epoch 想成展厅换展的编号。对象在旧展厅里被撤下后，不会立刻扔掉，而是贴上当前编号。正在访问旧展厅的线程会“固定”在一个纪元；只要还有人停留，旧展品就保留。当所有参与者都离开这个纪元，回收器就知道这一批对象不会再被新的访问看到，可以批量清理。\n\n典型实现会让线程进入临界区时 pin 自己，退出时 unpin。删除者把对象放入退休列表，随后观察全局或参与者的 epoch。只要退休对象的纪元比所有仍被固定的参与者都足够老，它就符合回收条件。和逐个扫描危险指针相比，这种方法更适合一次退休很多对象的场景，也能把回收工作批量化。\n\n它的难点是“停滞线程”。如果某个线程进入临界区后长时间不退出，旧对象可能一直不能释放，内存占用会逐渐升高。因此实际系统要监控 pinned 时间，区分慢线程、崩溃线程和真正仍在使用对象的线程。不同库还会在全局 epoch、局部 epoch、线程本地缓存之间做不同取舍。\n\n基于纪元的回收并不是传统垃圾回收：它通常没有对象可达性分析，也不会自动追踪所有引用，而是依赖并发数据结构遵守一套访问协议。它的价值在于把“每个对象有没有被某个线程读到”简化为“最老的活跃访问处在哪一代”。当读路径很短、参与者数量可控、删除可以延迟时，这种思路尤其漂亮。\n\n资料来源：[Crossbeam Epoch Documentation](https:\u002F\u002Fdocs.rs\u002Fcrossbeam\u002Flatest\u002Fcrossbeam\u002Fepoch\u002Findex.html)","\u002Fuploads\u002F2026-09-26\u002F2eb6fe27-ea9d-440a-877f-965f5158edb4.jpg",[],[],"Foundit","https:\u002F\u002Ffoundit.cn","foundit-ai-editorial",{"id":18,"name":19,"slug":20,"description":21},"6179d3b6-dc34-4483-9ded-3cd9f1b37a47","科普","abbreviation","介绍各领域新兴概念",[23,27,31],{"id":24,"name":25,"slug":26},"144abe77-0dc6-4f66-a176-20bddb1c0bfa","编程","coding",{"id":28,"name":29,"slug":30},"7c76bfc2-f80f-4ee0-a95d-27bd8708b434","技术","slug",{"id":32,"name":33,"slug":34},"68cedb55-2cac-412f-8f81-fda8c7d686dd","思考","thought",null,"Crossbeam Epoch Documentation","https:\u002F\u002Fdocs.rs\u002Fcrossbeam\u002Flatest\u002Fcrossbeam\u002Fepoch\u002Findex.html","published",false,43,0,"2026-09-27T00:00:00.000Z","2026-09-26T16:25:47.831Z",[45,53,62],{"id":46,"type":6,"title":47,"slug":48,"summary":49,"coverUrl":50,"authorName":14,"sno":51,"publishedAt":42,"createdAt":52},"3ee91529-a5cf-40b1-ab91-69df08e489ea","Hazard Pointers：无锁数据结构删除节点后，谁来保证它还没被读到？","hazard-pointers-memory-reclamation","Hazard Pointers 让线程在访问节点前公开保护标记，删除者延迟回收并扫描这些标记，从而避免悬空指针与部分 ABA 风险。","\u002Fuploads\u002F2026-09-26\u002Ffd52a815-7e19-4622-9182-6ca2df8e8144.jpg",42,"2026-09-26T16:25:44.416Z",{"id":54,"type":6,"title":55,"slug":56,"summary":57,"coverUrl":58,"authorName":14,"sno":59,"publishedAt":60,"createdAt":61},"05351c3a-3592-4ecb-aaeb-276a3bb2a79e","Abstract Interpretation：静态分析为什么不用真正运行程序？","abstract-interpretation-static-analysis-explained","Abstract Interpretation 用可计算的抽象状态近似程序行为，让工具在没有真实输入的情况下发现潜在问题。本文解释抽象、保守估计、循环收敛和误报，帮助读者理解静态分析为什么既强大又不总能给出确定答案。","\u002Fuploads\u002F2026-09-20\u002F3e0cf61b-b0dc-4028-b368-c4c013d026eb.jpg",41,"2026-09-20T00:00:00.000Z","2026-09-20T03:57:49.227Z",{"id":63,"type":6,"title":64,"slug":65,"summary":66,"coverUrl":67,"authorName":14,"sno":68,"publishedAt":69,"createdAt":70},"7418caa8-c69e-4dd7-bf51-795caea4a39d","Vibe Coding 时，为什么最容易泄露 API Key 和密码","vibe-coding-api-key-secret-leak","AI 编程最容易把秘密藏进前端、日志、配置和聊天上下文。本文解释浏览器端密钥、环境变量、日志暴露和 Agent 权限的风险，并给出适合个人项目的最小安全检查清单。","\u002Fuploads\u002F2026-09-13\u002F794d5f6a-d25b-4e2c-a002-cd743a31acff.jpg",47,"2026-09-13T00:00:00.000Z","2026-09-13T11:55:51.460Z"]