上一主题 下一主题
ScriptCat,新一代的脚本管理器脚本站,与全世界分享你的用户脚本油猴脚本开发指南教程目录
返回列表 发新帖

[转载] Closure 与 GC

[复制链接]
  • TA的每日心情
    擦汗
    2026-1-10 12:23
  • 签到天数: 1 天

    [LV.1]初来乍到

    7

    主题

    15

    回帖

    35

    积分

    助理工程师

    积分
    35
    发表于 2 小时前 | 显示全部楼层 | 阅读模式

    本帖最后由 cyfung1031 于 2026-2-5 20:47 编辑

    https://x.com/jarredsumner/status/2017825694731145388
    Screenshot 2026-02-05 at 20.00.28.png

    今天 Bun 的作者 Jarred Sumner 在推特上发了个文,说对于跑很久的 Claude code session 来说,底下的改动可以省掉 1GB 的记忆体:
    Before:() => controller.abort()
    After:controller.abort.bind(controller)
    从原本的 function 换成了 bind 的用法,为什么这样就可以呢?或是换个方式问,为什么原本的写法会吃比较多记忆体?
    在原文附图的注解里就有写原因了,说原本用 closure 的写法,会把整个 scope 记住,而这个 scope 有 request body 跟其他大的物件,所以在结束以前,这些被包住的东西都没办法被 GC,就会一直占空间。
    而修改后的做法没有 closure 了,所以不会记住那些无关的东西。
    这个问题其实在我的书《JavaScript 重修就好》里面就有提过了,有书的同学可以打开翻到 4-44,讲 closure 可能造成的潜在问题,我给了这样的案例:

    function createWebSocketHandler() {
      let socket = new WebSocket("wss://example.com/chat");
      let messages = [];
      socket.onmessage = function(event) {
        messages.push(event.data);
      };
      return {
        sendMessage: function(text) {
          socket.send(text);
        },
        closeConnection: function() {
          socket.close();
          socket.onmessage = null;
          socket = null;
        }
      };
    }
    const chatHandler = createWebSocketHandler();
    chatHandler.sendMessage("Hello, world!");
    chatHandler.closeConnection();

    在关闭连线时,我们将 socket close,然后把有用到 messages 的 onmessage 清掉,也把 socket 整个清掉,看起来没人用到 messages 了,就想说安全,既然没人用到那就可以被 GC 了。
    但这是在使用 closure 时会产生的错觉,那就是「只有我有用到的东西才会被记住」。事实上,closure 才没有在管你使用与否,只要是同一个 scope 的东西就全部记了下来。
    因此,尽管 sendMessage 与 closeConnection 这两个函式没有用到 messages, 它依然被引用了。所以就算把 socket.onmessage 给清除,messages 的记忆体空间还是没办法被回收。
    重点只有一个,就是 closure 是整个 scope 都会记著,被记住的东西就不会被 GC 了。这恰巧也是 Claude code 碰到的问题,没有察觉到那个被回传的 function 会记住整个 scope。
    然后这也跟 AI 写 code 一点关系都没有,一堆人类也会写出这样的 code,况且现在人跟 AI 谁写得比较好还很难说呢,尤其是对那些非工程师来说。
    这个案例是人是 AI 都有可能犯错,但如果是其他案例,当有人责怪 AI 怎么写出这种烂 code 的时候,AI 说不定会想跳出来抱怨:「我才不会犯这种错呢,这一定是人类写的」。

    发表回复

    本版积分规则

    快速回复 返回顶部 返回列表