You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Racket中custodian-limit-memory未触发内存不足错误?

问题原因

你当前的代码只是通过parameterize临时切换了current-custodian参数,但运行代码的当前线程仍然属于顶级custodian(程序启动时默认的custodian)。Racket中,对象的内存归属由创建它的线程所属的custodian决定,而非当前current-custodian参数的值。因此你设置的2MB内存限制根本没有作用在make-bytes的内存分配上,自然不会触发内存不足错误。

修正方案

要让custodian的内存限制生效,必须让内存分配操作在由该custodian管理的线程中执行。你需要创建一个新线程,并将该线程的归属custodian设置为你创建的带内存限制的custodian。

修正后的代码如下:

#lang racket/base

(with-handlers
  ([exn:fail:out-of-memory? (λ (err)
                               (println "Caught out-of-memory error! :D"))])
  (let ([limit-custodian (make-custodian)])
    ; 设置2MB内存限制
    (custodian-limit-memory limit-custodian (* 2 1024 1024))
    ; 创建由limit-custodian管理的线程
    (define mem-hog-thread
      (thread
       (λ ()
         ; 切换current-custodian,确保对象归属到目标custodian
         (parameterize ([current-custodian limit-custodian])
           (make-bytes (* 4 1024 1024))))))
    ; 等待线程执行,触发可能的异常
    (sync mem-hog-thread)
    (println "Should have raised OoM. :(")))
补充说明
  • 线程创建后必须用sync等待执行结束,这样才能捕获到线程因内存限制被终止时抛出的异常。
  • parameterize ([current-custodian limit-custodian])确保线程内创建的对象归属到目标custodian,让内存限制能够正确统计这些对象的大小。
  • 当custodian管理的内存总和超过限制时,Racket会先尝试垃圾回收,若回收后仍超过限制,则会终止该custodian下的所有线程,并抛出exn:fail:out-of-memory异常。

内容的提问来源于stack exchange,提问作者Cazra

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.17 17:45:30