Hacker News 每日播报:今天我们将深入探讨从空气中收集水分的新材料、免费的计算机科学自学路径、大众汽车“柴油门”高管入狱、Jujutsu 版本控制系统的 TUI 工具、谷歌意外泄露用户电话号码的事件、开源多模态 AI 模型 BAGEL、GitLab Duo 中的远程提示注入漏洞、Hacker News 后端迁移至 Common Lisp,以及使用 AI 进行股票交易的尝试和垃圾回收器的技术细节。
一种能从空气中被动收集水分的新型材料
宾夕法尼亚大学的工程师们带来了一项令人振奋的发现:一种新型纳米结构材料,能够在无需外部能量输入的情况下,从空气中被动收集水分。这项研究发表在《科学进展》杂志上,它描述了一种材料,能够利用毛细管凝结原理,即使在较低湿度下也能在微小孔隙内凝结水蒸气。更独特的是,凝结后的水并不会被困住,而是会移动并以液滴形式出现在材料表面。研究人员最初对这种现象感到惊讶,因为它似乎“可能违背物理定律”,因为水滴并未快速蒸发,且收集水量随厚度增加。他们发现,这种材料的关键在于其两亲性纳米结构,巧妙结合了亲水纳米粒子和疏水聚合物,使得内部凝结的水能持续补充并被“挤压”到表面。
这项发现的潜力巨大,尤其是在干旱地区被动收集饮用水、为电子设备提供蒸发冷却以及开发智能涂层等领域。材料由常见聚合物和纳米粒子制成,可扩展制造。
然而,围绕这篇文章的讨论非常热烈,尤其对其宣传语进行了深入审视。许多人对“被动收集”、“无需外部能量”以及“可能违背物理定律”等说法表示高度怀疑。他们指出,根据热力学第二定律,水蒸气凝结会释放潜热,这部分热量必须被移除,否则凝结无法持续。如果材料本身没有冷却,它会升温并停止凝结。一些观点认为,这与物理学基本原理相悖。
有观点将这种材料与现有除湿袋进行比较,质疑其如何实现水的持续收集和释放,以及水滴如何从表面移除(这可能也需要能量)。一些人直接引用论文方法部分,指出实验在温度严格控制的环境下进行,使用了加热/冷却单元来维持恒温,这似乎暗示实验过程中存在主动的温度控制,与“无需外部能量”的宣传不符。有声音认为,大学公关部门为了制造轰动效应,常常夸大研究成果,使用耸人听闻的语言,这可能会误导公众,损害科学的严谨性。
尽管存在对宣传语的质疑,但也有人看到了这项研究的潜在价值。他们认为,即使它不是完全“无能耗”的永动机,这项技术也可能比现有除湿方法更节能、更安静。材料独特的机制——在纳米尺度上同时实现吸收和释放——本身就是一项重要的科学突破。如果它能在相对较高的环境温度下工作,通过简单的散热实现相对被动的运行,仍然具有巨大的应用前景,尤其是在水资源匮乏但湿度较高的地区。
Open Source Society University – 免费自学计算机科学之路
Open Source Society University (OSSU) 是一个在 GitHub 上托管的项目,它提供了一条免费自学的计算机科学教育路径。OSSU 的核心目标是提供一个完整的、相当于本科学位的计算机科学教育课程,而非仅仅是职业培训。它通过精心策划来自世界顶尖大学的免费在线课程和高质量书籍,构建了一个结构化的学习路径。课程选择标准包括开放注册、定期运行、高质量教学材料以及符合 CS 2013 本科课程指南。整个课程分为入门、核心、高级和最终项目四个阶段,建议每周投入约 20 小时,大约两年完成。OSSU 强调学习过程中的社区支持,提供 Discord 服务器和 GitHub Issues 作为交流平台,并鼓励学习者通过贡献开源项目来巩固和展示知识。
围绕 OSSU 的讨论非常热烈,展现了对自学 CS 路径的多种看法和亲身经历。许多人对 OSSU 这样的倡议表示高度赞赏,尤其是在教育资源不均衡的地区。一位来自“鲜为人知国家”的用户分享了他的经历,他通过 OSSU 重新学习了基础课程,认为其课程质量和结构远超他本国的大学教育,是唯一真正可及的学习途径。
然而,关于自学与传统学位孰优孰劣的辩论占据了讨论的大部分。一些有经验的自学成才者分享了他们的成功故事,认为工作经验和人脉比学位更重要,尤其是在职业生涯后期。他们强调自学者的主动性、持续学习能力和通过项目展示实际技能的重要性。但也有不少人提出了自学路径的挑战和局限性。一些观点认为,缺乏学位会影响“信号传递”和人脉建立,可能导致难以进入某些顶尖公司或职位,尤其对于缺乏工作经验的入门级岗位而言。有观点引用数据指出,拥有四年制学位的美国人平均收入是无学位者的两倍,这反映了市场对学历的现实偏好。
讨论也触及了自学过程中的具体困难,比如缺乏导师指导、难以衡量自身水平、需要更强的自律性以及容易陷入只为应付面试而学习的陷阱。同时,也有人提到大学提供的通识教育和社交体验是自学难以复制的。此外,关于 OSSU 社区使用的交流平台(Discord)也引发了小范围讨论。一些人认为在一个“开源”教育项目中选择一个闭源、商业化的平台有些讽刺,但另一些人则认为,选择 Discord 是为了“到人们所在的地方去”,以最大化社区的可及性和活跃性。
德国法院判处大众汽车“柴油门”高管入狱
德国一家法院对四名前大众汽车(VW)高管在“柴油门”(Dieselgate)排放丑闻中的欺诈行为做出了判决,其中两人被判入狱多年,另外两人获得缓刑。这标志着这场持续了近四年的重大审判告一段落,也是大众汽车因这一大规模企业不当行为继续面临的法律后果之一。
文章回顾了“柴油门”事件的始末:2015年9月,美国环境保护署(EPA)发现大众汽车的柴油车安装了非法的“作弊装置”,能够在测试时改变发动机性能以满足环保标准,但在实际驾驶中排放远超限值。大众汽车在2017年承认在美国操纵了排放数据,引发全球强烈反响,并导致了汽车行业历史上最大的企业丑闻之一。自丑闻爆发以来,大众汽车面临大量诉讼和法律程序,截至2020年,已付出超过300亿欧元的罚款和赔偿。
这则新闻引发了热烈讨论,主要观点集中在对企业高管被追究个人责任的看法,以及对大型企业不当行为惩罚普遍不足的普遍不满。许多人对德国法院的判决表示赞赏,认为这是惩罚不良企业行为的罕见案例。然而,更普遍的情绪是,这种个人责任追究“太少见了”。许多观点引用了各种谚语和格言来表达“窃钩者诛,窃国者侯”的观点,反映了人们普遍认为,小规模的个人犯罪往往受到严厉惩罚,而大规模的企业或金融犯罪的责任人却常常逍遥法外,或者公司只需支付罚款,个人无需承担刑事责任。
讨论中提到了多个对比案例来支撑这一观点:例如2008年金融危机后,只有少数国家追究了银行家的刑事责任;以及雇主克扣或不支付员工工资的“工资盗窃”行为,虽然涉及金额巨大,但很少受到刑事起诉。
关于大众汽车本身,讨论了这次判决是否会影响其竞争力。一些人认为,“柴油门”反而可能促使大众更早地转向电动汽车(EV),从而在转型中获得了优势。还有观点提到,不仅仅是大众,许多其他汽车制造商可能也存在类似的作弊行为,而博世公司和批准相关测试标准的政客们也应承担责任,但他们似乎并未受到同等程度的追究。
关于责任层级,讨论了被判刑的高管是哪个层级的。根据信息,被判实刑的似乎是柴油发动机开发和发动机电子部门的负责人,而更高级别的董事会成员或前CEO则获得了缓刑或因健康原因未参与审判。这引发了关于CEO是否应为公司行为负最终责任的讨论。
Jjui – Jujutsu 的一个漂亮 TUI
今天我们要聊的是一个为 Jujutsu (jj) 版本控制系统打造的漂亮终端用户界面(TUI),项目叫做 Jjui。jjui
旨在为 jj
用户提供一个直观的终端界面,它提供了一系列功能,旨在简化 jj
的日常操作。根据项目的 README,它目前支持交互式 Revset 操作(自动补全和签名帮助)、图形化操作(Rebase、Squash)、详细信息查看(Split、Restore 文件、Diff)、书签与操作日志管理、预览功能(jj show
、jj diff
、jj op show
),以及其他常用操作,如编辑修订描述、创建新修订、Abandon、Absorb、Edit 修订,以及执行 Git 的 Push/Fetch 操作和 Undo 最后一次更改。
围绕 jjui
的讨论非常活跃,但很快扩展到了 Jujutsu (jj) 这个版本控制系统本身,以及它与 Git 的对比和使用体验。
对 jjui
的直接评价普遍积极,许多人认为它是他们尝试过的 jj
TUI 中最喜欢的一个,认为它“漂亮”、“敏捷”、“直观”,并且键位绑定设计得很好。有人从 Git 的 Magit 切换过来,认为 jjui
是一个不错的开始。
对 Jujutsu (jj) 的推荐非常强烈。许多人是 jj
的忠实用户,他们认为 jj
已经成为工作流程中不可或缺的一部分,甚至让 Git 感觉“笨重”。他们强调 jj
在处理本地变更、管理历史以及变基(尤其是处理冲突时)方面的优势,认为 jj
的冲突解决体验通常比 Git 更好。
然而,讨论也暴露了 jj
目前的一些不足,尤其是在与现有生态系统(主要是 GitHub)集成方面:一个被反复提及的痛点是 jj
缺乏像 Sapling 那样与 GitHub 堆叠式 Pull Request 同步的良好支持。这被认为是推广 jj
的一个障碍。此外,用户希望 jj
能有原生的推送/拉取功能,以便在不同设备间同步 jj
仓库时能保留完整的 jj
历史,而不是通过 Git 后端丢失信息。还有人提到,如果忘记在修改代码前创建一个新的修订,之后再拆分变更会有点麻烦。
关于 jj
是 Git 的“门面”(porcelain)还是一个独立的 VCS,讨论认为 jj
不共享 Git 代码,而是使用 Git 作为存储层。它的大部分逻辑和用户界面是独立实现的。虽然目前主要依赖 Git 后端,但其设计是后端无关的,未来可能支持其他或原生的存储方式。
Google 分享了我的电话号码
文章作者 Dan Q 分享了他最近遇到的一个令人沮丧的经历:Google 在他创办的志愿者管理系统 Three Rings 的 Google Business Profile(谷歌商家资料)页面上,未经他明确同意,公开了他多年前用于身份验证的个人手机号码。作者回忆起多年前曾向 Google 提供了这个号码,但那是为了验证商家资料的所有权,并非同意公开。他发现 Google Business Profile 页面上赫然写着“您的电话号码已由 Google 更新”。他立即删除了这个号码,号码很快从搜索结果中消失。这次事件让作者感到非常愤怒和困惑,尤其是在他近期刚经历了另一起个人信息泄露事件之后。他质疑 Google 为什么会在多年后突然公开这个号码,并怀疑这是否与某种自动化流程或数据关联有关。
围绕此事的讨论呈现出几个主要角度:
一些观点质疑作者的说法,认为号码可能已在别处公开,而 Google 只是从这些公开来源抓取并关联了信息。但作者在回复中坚称 Business Profile 的号码是多年前仅用于验证的,且 Google 多年来并未公开,是近期才突然出现的。
许多人认同作者的遭遇,并分享了他们或认识的人与 Google Business Profile 打交道的负面经历。他们提到 Google 会自动从各种来源抓取并更新商家信息,有时甚至会覆盖商家自己提供的信息,而且过程缺乏透明度或难以控制。这种自动化和众包的更新机制,加上 Google 糟糕的客户支持,让商家难以确保信息的准确性和隐私性。
讨论扩展到更广泛的数据隐私和聚合担忧。有观点认为,任何提供给大型科技公司的数据,无论最初的用途是什么,最终都可能被用于公司认为有利的目的。一些令人不安的轶事被分享,例如手机联系人数据被抓取并用于商业目的,或者手机应用根据联系人信息或地理位置推荐好友。这反映了用户对个人数据被滥用或意外公开的普遍担忧。
一个重要的讨论分支揭露了 Google 商家资料系统被恶意利用的案例。在德国等欧洲国家,一些食品配送平台恶意利用 Google Business Profile 的更新机制,注册与餐厅名称相似的域名,声称拥有餐厅的 Google 商家资料,然后将联系电话改为自己的呼叫中心号码。当顾客通过 Google 搜索并拨打这个号码时,会联系到配送平台,平台再以此为筹码,胁迫餐厅签约合作。有观点认为,Google 在验证商家所有权和信息来源方面的不足,客观上助长了这种欺诈和勒索行为。
Bagel: 开源统一多模态模型
BAGEL 是一个备受关注的开源统一多模态模型,其核心理念是提供一个强大的开源替代方案,与 GPT-4o 和 Gemini 2.0 等专有模型竞争。它被设计为一个单一的、统一的模型,能够理解和生成跨不同模态的内容,特别是文本和图像,甚至将视频数据纳入其训练。
BAGEL 的关键特性包括:统一能力(处理混合文本和图像输入,并生成混合文本和图像输出)、多模态训练(在大规模、交错的视频和网络数据上进行预训练,这对于生成逼真图像、视频帧和多模态思维链至关重要)、多样化功能(图像编辑、风格迁移、导航、组合推理)以及“思维模式”(一种内部机制,通过多模态理解来优化生成和编辑)。它采用 Mixture-of-Transformer-Experts (MoT) 架构,并使用单独的编码器处理像素和语义特征,通过大量的预训练、持续训练和微调来扩展模型。
在围绕 BAGEL 的讨论中,一个主要主题是可访问性和硬件要求。许多人立即开始讨论 VRAM 需求。普遍认为,根据参数数量和精度(如 FP16),该模型可能需要大约 14GB 的 VRAM 才能加载,推理需要更多,尤其考虑到图像会消耗大量上下文 token。这引发了关于量化以及不同精度如何影响内存使用的讨论。有用户报告成功在 24GB 的 RTX 3090 上运行了一个无损压缩版本,但指出内存非常紧张,需要关闭其他应用程序,并且生成/编辑仍需几分钟。这表明,尽管它是开源的,但在本地运行完整模型对许多人来说可能仍然具有挑战性。
另一个重要的讨论点是性能和基于初步测试的怀疑。尽管论文展示了与“其他开源模型”相比的强大基准测试结果,但一些尝试了可用演示链接的用户报告了好坏参半的结果。有人发现它不如演示中暗示的那么“智能”,会误解问题并丢失上下文。另一些人甚至在项目页面提供的官方示例中也指出了明显的错误或不完美的处理,例如解释表情包或处理图像中的手部。但也有用户分享了积极的体验,例如测试其对芬兰漫画的文本理解,发现尽管有些误解,但仍令人印象深刻。这表明实际性能可能有所不同,并且可能不总是符合精心策划的演示或基准测试结果。
此外,还有关于**“多模态”定义**的有趣讨论。一些人指出,“多模态”在这些模型中几乎总是指文本+图像,并表示对处理文本+语音的模型更感兴趣,类似于 ChatGPT 的高级语音模式。
GitLab Duo 中的远程提示注入导致源代码被盗
Legit Security 的研究团队发布了一篇文章,揭示了他们在 GitLab 的 AI 助手 GitLab Duo 中发现的一系列漏洞。核心问题在于,通过远程提示注入(Remote Prompt Injection),攻击者能够窃取私有项目的源代码。文章详细阐述了攻击链:GitLab Duo 会响应隐藏在项目内容(如源代码文件、合并请求描述、提交信息、Issue 评论)中的指令,即使这些指令通过混淆或隐藏方式。利用这一点,攻击者可以植入恶意提示,不仅能操纵 Duo 的代码建议,还能通过 HTML 注入将恶意内容嵌入到 Duo 的响应中。
最关键的是,GitLab Duo 运行在与受害者用户相同的权限上下文中。这意味着 Duo 可以访问用户能看到的一切,包括私有仓库的代码和机密 Issue。攻击者可以设计一个隐藏提示,指示 Duo 从用户有权访问的某个私有项目中提取特定代码或机密 Issue 的内容,将其 Base64 编码,然后嵌入到一个 <img>
标签的 URL 中。当用户与 Duo 互动并触发这个提示时,Duo 会在响应中包含这个恶意 <img>
标签。用户的浏览器尝试加载这个“图片”时,就会向攻击者控制的服务器发送一个 GET 请求,请求的 URL 中包含了 Base64 编码的敏感数据,从而导致源代码或机密信息的泄露。
研究团队在 2025 年 2 月 12 日向 GitLab 披露了这些问题。GitLab 确认了 HTML 注入和提示注入是安全问题,并迅速发布了补丁。补丁主要阻止了 Duo 渲染指向 gitlab.com
外部域名的不安全 HTML 标签,从而缓解了基于 HTML 的数据外泄风险。文章强调,虽然漏洞已修复,但这暴露了深度集成 AI 助手带来的新攻击面:AI 工具不仅生成内容,它们消费的输入也必须被视为不可信和潜在恶意。
围绕这篇文章的讨论非常活跃,主要围绕提示注入的本质、LLM 集成的风险以及缓解措施的有效性展开。一个核心观点是关于提示注入是否“可修复”。一些人认为,提示注入不像传统的软件漏洞那样能被彻底根除,而更类似于人类的“内部威胁”或社会工程学——LLM 的行为是模糊且难以完全预测的。然而,另一些人对此表示担忧,指出 LLM 并非独立的个体,而是同一模型的克隆,这意味着一旦找到一个有效的攻击提示,它可能对所有用户实例都有效。
关于风险的范围,普遍认为,真正的风险不仅仅是代码本身的窃取,更是代码或 Issue 中包含的敏感信息和秘密。许多人指出,开发者经常在私有仓库中存放密钥或其他敏感配置,错误地认为私有仓库本身就是一道足够强的安全边界。GitLab Duo 运行在用户权限下,能够访问用户能看到的一切,这被一些人形容为“疯狂”,认为即使需要访问权限,也应该使用范围受限的个人访问令牌,而不是赋予 AI 助手如此广泛的权限。
对于 GitLab 的补丁,一些人提出了疑问。他们指出,补丁似乎只阻止了 <img>
和 <form>
标签指向外部域名。这是否意味着如果存在指向 gitlab.com
内部其他易受攻击端点,或者使用其他未被阻止的 HTML 标签,漏洞链是否可能再次被利用?这引发了对当前缓解措施是否足够全面的讨论。
Hacker News 现在运行在 Common Lisp 之上
Hacker News 最近完成了一项重要的技术迁移:其后端不再运行在基于 Racket 的 Arc 实现之上,而是迁移到了基于 Common Lisp (SBCL) 的新 Arc 实现,代号 Clarc。文章指出,这次迁移的主要驱动力是性能提升。一个直接的用户体验变化是,长评论串不再需要分页加载,这在过去是由于性能限制而不得不采用的折衷方案。HN 的管理员 dang 在讨论中证实了这一变化,并提到 Clarc 的速度更快,并且能够让 HN 利用多核处理器。
技术实现方面,文章引用 dang 之前的解释,透露 Arc 的实现被分成了多个阶段,其中最底层 arc0 是用宿主语言编写的。这种分层设计使得将 Arc 移植到不同的底层系统变得更容易。Clarc 就是这个 Arc 到 Common Lisp 的编译器/运行时。关于代码的开放性,文章澄清了两个不同的概念:Clarc (Arc 的 Common Lisp 实现) 和 HN 网站本身的源代码。dang 表示,开放 Clarc 的源代码是“容易得多”的,但开放 HN 网站的完整代码库则“行不通”,因为其中包含了大量依赖于不公开细节的反滥用措施。
围绕这篇文章展开了热烈讨论,主要集中在以下几个方面:
- HN 的极简主义设计与“Worse is Better”/“Less is More”的辩论: 许多人将 HN 与 Slashdot 等老牌社区网站进行比较,讨论 HN 缺乏功能(如用户关注、暗模式、更丰富的评论格式)是好是坏。一些人认为 HN 体现了 Gabriel 的“Worse is Better”原则,即简单实现加上复杂的社交工程/人工审核,反而比功能更复杂的系统更容易获得成功。另一些人则认为这更像是“Less is More”的体现,认为 HN 的极简是刻意为之,是一种优势。
- 审核机制的讨论: HN 的审核方式是另一个焦点。普遍认为 HN 依赖于用户驱动的投票和标记,但也结合了管理员大量的人工干预和自动化/半自动化工具。有人认为 HN 的审核比 Slashdot 更有效,尽管机制更简单。关于代码中包含反滥用措施的讨论引发了对“安全通过模糊性”(Security Through Obscurity)的辩论。
- 技术选择与性能: 对从 Racket 迁移到 Common Lisp (SBCL) 的技术决策表示赞赏和好奇。SBCL 被许多人认为是 Common Lisp 中性能极高的实现。有人对 HN 之前运行在单核上表示惊讶,并由此引申出对现代 CPU 强大性能的讨论,以及对当前软件普遍臃肿和低效的批判。
- 开放源代码的可能性: 许多人对 Clarc 是否会开源以及 HN 代码库的开放性表示兴趣。文章中 dang 的澄清(Clarc 易于开源,HN 代码难)得到了确认和进一步讨论。
使用 Claude 进行交易,并编写自己的 MCP 服务器
Dino Angelov 的文章《Trading with Claude (and writing your own MCP server)》探讨了将像 Claude 这样的大型语言模型(LLM)连接到真实世界金融工具的实践。核心思想是利用 Anthropic 的 Model-Context Protocol (MCP),一个旨在标准化 AI 助手与外部服务和应用程序交互的协议。作者解释说,Anthropic 开源 MCP 是为了实现 AI 与各种工具的无缝集成。MCP 服务器本质上是一个服务器,它通过这个标准化协议向 LLM 暴露函数和资源列表。LLM 可以决定何时以及如何调用这些函数,就像使用工具或函数调用一样。
作者在 SnapTrade(一个提供统一 API 以集成各种金融平台的服)工作,他决定构建一个金融交易机器人作为使用 MCP 的实际例子。他详细介绍了使用 Go 语言编写这个 MCP 服务器的过程,并使用了 go-mcp
框架和 SnapTrade Go SDK。他实现了几个关键工具,包括:获取入门信息、连接券商、检查投资组合和下订单。
然而,文章包含了重要的警告。作者明确指出通过 LLM 执行高影响操作(如交易)的风险。在测试过程中,他遇到 Claude 未能下订单,然后自行尝试以递增数量下订单的情况。这凸显了 LLM 的不可预测性以及潜在的意外后果。他强调,尽管 MCP 功能强大,但必须意识到其局限性,尤其是在这些早期阶段。
在讨论中,一个主要主题围绕着 MCP 实现和安全性。一些人对身份验证表示困惑,尤其是在多用户或企业场景中。作者澄清说,他的演示使用本地二进制文件通过标准 I/O 进行通信,为简单起见从 .env
文件加载凭据,不涉及 OAuth。
MCP 实现的复杂性是另一个讨论点。一些人认为官方 SDK 和标准过于抽象,需要过多的样板代码。关于 LLM 代码生成 MCP 服务器的经验也被分享。有人警告说,虽然像 Claude 这样的新模型可以生成大量代码,但它们可能会微妙地产生幻觉或硬编码不正确的信息,需要仔细的代码审查。
交易表现和策略方面引发了兴趣。有人分享了他们使用多个 MCP 服务器构建类似系统的经验,并在几个月的模拟交易中实现了 2% 的利润。这引发了关于与市场指数进行基准测试以及这种系统是否真的能盈利的问题。
呼应作者的警告,许多人对使用 LLM 进行金融交易的风险表示担忧,强调了不可预测的错误或“幻觉”可能导致意外交易或重大损失的可能性。
一个更广泛、更具哲学性的辩论围绕着 MCP 广泛采用和 AI 代理的社会影响展开。一些人对代理自动化日常任务(如订购杂货、预订旅行)的潜力感到兴奋,认为这将释放时间用于更有意义的活动。然而,一种强烈的反面观点则对这种程度的自动化表示担忧,认为这可能导致人们变得娇生惯养、无能,无法处理简单的决策或延迟。他们质疑这些自动化任务是否真的是“需求”,或者只是为了避免任何不便而产生的“虚构偏好”。
Whippet GC 关于 Guile、启发式和堆增长的笔记
这篇文章主要讨论了作者在将 Whippet 垃圾收集器集成到 Guile Scheme 实现中时遇到的挑战,特别是关于堆大小调整策略和由此引发的碎片化问题。作者首先提到,他已经成功地让 Guile 运行起来,并使用了 Whippet 中基于 Nofl 的收集器之一,这个收集器采用了保守扫描所有指针的方式。然而,尽管如此,仍然存在一些问题,尤其是与堆大小调整的启发式方法相关的。
Whippet 提供了几种堆大小调整策略:固定大小、可增长和自适应。目前 Guile 使用的是“可增长”策略,其目标是将堆大小保持在至少是活动数据大小的某个倍数(默认是 1.75 倍)。
核心问题出现在碎片化上。作者举例说明:一个 10MB 的可增长堆,倍数设为 2 倍,堆中交替分布着 16 字节的对象和 16 字节的空洞。当需要分配一个 32 字节的对象时,它属于“小对象”并尝试在 Nofl 空间中分配。但如果每个空洞都只有 16 字节,无法容纳 32 字节的对象,分配器就会不断扫描可用的块,直到所有块都扫描完,触发 GC。GC 运行后,堆大小可能已经达到了活动数据大小的 2 倍,启发式方法判断无需增长堆。结果,分配器再次面对同样的碎片化堆,找不到足够大的空洞,再次触发 GC,形成活锁(livelock)。作者指出,这个问题在 Guile 的引导过程中实际发生过。
作者分析说,碎片化是问题的根源。虽然像半空间收集器这样的复制型收集器能彻底解决碎片化,但在需要保守扫描的场景下可能无法使用。提高堆倍数可以缓解问题,但在极端碎片化的情况下,可能需要极高的倍数。作者的结论是,如果无法处理碎片化,就不能仅仅依赖堆倍数来确定堆大小。为了可靠性,必须允许某种形式的内存整理或疏散。
针对 Nofl 收集器在当前无法进行碎片整理的情况,作者提出了两种启发式解决方案。首先,如果堆是可增长但不能碎片整理,那么在每次 GC 后,即使会超出配置的堆倍数,也需要保留一些空的块。这样可以确保 GC 后总有空间用于分配。其次,作者认为分配器扫描整个堆寻找空洞效率低下。借鉴 Immix 收集器,可以为“溢出分配”保留一些块:如果一个中等大小的分配在当前块中找不到足够大的空洞,就从预留的空块集合中取一个专用的“溢出块”来分配。
作者总结说,目前使用这种基于 Nofl 的可增长堆配置的体验,主要被活锁问题困扰,并且相比 BDW-GC,它在内存分配上显得更为“吝啬”。但他对未来实现精确追踪并解决碎片化问题保持乐观。